_read函数的一个陷阱

晚上用evhttp编了一个http服务器,请求静态文件的时候,发现半天没反应。

vs 2013的调试器也很奇怪,按个F10直接跳到下一个断点了。点击下断点的时候,提示“断点未能绑定”。后来,在网上搜到了解决办法:在  工具 -- 选项  --  调试  --  编辑并继续 里面 勾选启用本机“编辑并继续”。

解决了这个问题,就调试一步步跟踪吧。

代码中,先用open打开文件,然后调用evbuffer_add_file将文件内容拷贝到缓冲区。

贴上一段evbuffer_add_file的代码:

while (length) {
	read = evbuffer_readfile(tmp, fd, (ev_ssize_t)length);
	if (read == -1) {
		evbuffer_free(tmp);
		return (-1);
	}

	length -= read;
}

这个length最初是用fstat函数计算出来的。  evbuffer_readfile里面调用的是read函数。

调试发现,直到read到文件末尾的时候,这个length还不为0。

疯了,微软的bug吗?  open、fstat、read都是crt函数,但是从read读取统计出的大小竟然跟fstat的大小不一样。。。

折腾了半天,写了下面一段代码,测试是不是真的有这个问题。

#include <fcntl.h>
#include <share.h>
#include <io.h>
#include <sys/stat.h>
#include <sys/types.h>

int _tmain(int argc, _TCHAR* argv[])
{
	struct _stat buf;
	int fd;
	char buffer[1024];
	_sopen_s(&fd, "D:\\Code\\httpsvr\\Debug\\ReadMe.txt", O_RDONLY, _SH_DENYWR, 0);
	_fstat(fd, &buf);
	
	int length = buf.st_size;
	while (length > 0)
	{
		int nread = read(fd, buffer, 1024);
		length -= nread;
	}
	close(fd);
	return 0;
}
跑起来,果然死循环了。简直不敢相信啊。。。

想来想去,折腾了一个多小时。。  

微软可能这么SB吗  感觉不应该吧,再查查msdn。直到看到下面一段解释,才算明白了究竟是怎么回事。。

<p>_ <span style="FONT-WEIGHT: bold">read</span> returns the number of bytes read, which might be less than <span style="FONT-STYLE: italic">count</span> if there are fewer than <span style="FONT-STYLE: italic">count</span> bytes left in the file or if the file was opened in text mode, in which case each carriage return–line feed (CR-LF) pair is replaced with a single linefeed character. Only the single linefeed character is counted in the return value. The replacement does not affect the file pointer.</p>
如果是在TEXT模式下打开的,那么_read函数会将CR-LF合并成一个换行符,但保持文件指针位置一致。

把open的模式增加一个_O_BINARY就好了。

_sopen_s(&fd, "D:\\Code\\httpsvr\\Debug\\ReadMe.txt", O_RDONLY | _O_BINARY, _SH_DENYWR, 0);






你可能感兴趣的:(_read函数的一个陷阱)