赞
踩
一般情况下,我们只在linux平台下使用open,read等文件I/O函数,《UNIX环境高级编程第二版》中介绍他们是POSIX.1标准的组成部分。
笔者偶然的机会将Linux下的程序移植到windows平台下,却发现这些函数同样可以使用,但需要加入头文件io.h ,同时遇到了下面的一个问题。
文件src_file如下:
测试代码如下:(buf1,buf2均初始化为0)
fsrc = fopen(src_file,"r+");
fsrc2 = open(src_file,O_RDONLY);
int rwsize = fread(buf1,1,10,fsrc);
int rwsize2 = read(fsrc2,buf2,10);
分别用read和fread方式打开,两者的结果不一样。rwsize = 10,rwsize2 =9.
buf1[0]='0A',后面是123456789
buf2[0]='0A',后面是123456788
buf1的结果容易理解,因为windows对回车换行的处理原因,再写入‘0a’之前都会加入‘0d’,同理在读取时也会自动忽略‘0d’,所以跳过最初的‘0d’后再读取了10个字节的内容,返回值也是10.
buf2的结果则让人困惑,它也没有读取‘0d’,但是返回值只有9,说明计数的时候又算了‘0d’的个数,而且最后的8怎么出现的也未可知。经过尝试,发现最后一位总是和倒数第二位相同。
后来查阅了MSDN上的官方资料,发现了open函数的以下说明。
我们在学习unix编程的时候,open是没有这两个选项的,因为在linux下打开的都是字节流。但是在windows环境下就不同了,因为文本方式和二进制方式对待0d,0a操作是不同的,二进制方式不会省略0d.
如果通过fsrc2 = open(src_file,O_RDONLY|_O_BINARY)方式打开fsrc,则会得到rwsize2=10 ,buf[0]='0d',buf[1]='0a',后面为12345678.这个结果就容易理解了。
对于一开始得到的123456788,msdn上的read函数有以下说明,
_read returns the number of bytes read, which might be less than count if there are fewer than count 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
由此我们可以知道为什么返回值为9,但是buf2的值为什么倒数第一位和第二位会相同,这个恐怕得通过反汇编看read内部的实现了。
小结:当移植linux代码到windows下事,要记得使用二进制模式打开和操作文件,文本方式使用read函数很容易出现上述为题。如果一定要使用文本方式,就采用标准I/O库函数吧,fopen,fread等。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。