windows平台下使用open,read等函数易错点及与fread等区别

本文探讨了在Windows平台上使用POSIX风格的文件I/O函数如open和read时遇到的问题,尤其是在文本模式与二进制模式下的差异。通过对比fread和read函数的行为,揭示了文本模式下对换行符的不同处理导致的数据读取差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一般情况下,我们只在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等。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值