fread函数以二进制模式和文本模式打开的区别

来源:互联网 发布:中国孩子 知乎 编辑:程序博客网 时间:2024/04/30 05:54

文件1.txt中的内容如下:

  “123”

   “456”

用下面的方式统计文件的字节数:   

    fp = fopen("1.txt", "r");

    fseek(fp, 0, SEEK_END);
    file_len = ftell(fp);

则file_len统计了文件1.txt中的字节数为:8

用函数 readLen = fread(data, 1, num, fp);读取到的字节数为:7

 

为什么两者会不一样呢?

 

 函数声明:int fread( void *buffer, size_t size, size_t num, FILE *stream );

说明:函数fread()读取[num]个对象(每个对象大小为size(大小)指定的字节数),并把它们替换到由buffer(缓冲区)指定的数组。数据来自给出的输入流,函数的返回值是读取的内容数量。

如果此时,需要读一个1024字节的文本,那么可以设置size为1,num为1024。当然,可以是size为1024,num为1。

问题也就来了,这两种方式哪个好呢。。。我习惯的是前者,这样的话fread的返回值为读入的字节数。及时读入有问题,也比较容易发现。而如果是后者,那么当fread没有读入预想到的长度(比如size = 1024)那么fread的返回值会是0这就比较麻烦了。。。

这还有问题可能更有意思,一开始还真没怎么注意到,先看一段MSDN:

If the given stream is opened in text mode, carriage return–linefeed pairs are replaced with single linefeed characters. The replacement has no effect on the file pointer or the return value.

就是说如果按“文本模式”打开一个文件,那么在读入的时候,Windows默认的换行符CR+LF就会转换成一个单个的LF。

那么也就是说,如果一个文本文件的大小为1024字节,一共100行,那么fread最多只能读入924个字节。

在这种情况下,fread( buffer, 1, 1024, stream )的返回值将会是924个字节。
fread( buffer, 1024, 1, stream )的返回值,将会是0 。。。-_-!

 

 

这也就解释了开始为什么两者统计的结果会不一样。当我们把开始的改成下面形式:(即以二进制模式打开文件)

 

用下面的方式统计文件的字节数:   

    fp = fopen("1.txt", "rb");

    fseek(fp, 0, SEEK_END);
    file_len = ftell(fp);

则file_len统计了文件1.txt中的字节数为:8

用函数 readLen = fread(data, 1, num, fp);读取到的字节数为:8

 

这也两者的结果就一样了。

原创粉丝点击