免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6333 | 回复: 14
打印 上一主题 下一主题

问个fread的未知问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-07-02 10:50 |只看该作者 |正序浏览
本帖最后由 houtinghua 于 2010-07-02 11:21 编辑

fread一个打开的文件流,文件长度100;
int r = fread( buf,1,100,fp );
这个时候fread有没有可能返回70,我的意思是说fread的过程中没有发生普通意义上的错误,只是一次没读那么多,让你再fread一次,读取100-70=30个字节呢?

因为我看函数介绍说fread返回实际读取的,但是没有确切说明实际读取的字节必须等于100

不知道你们看明白我想说什么了吗


把下面的提上来  怕你们不往下看

以返回的长度为准。如果不足是要再读的。至于这种情况是否发生,和平台以及fread()实现情况有关。你不能假设 ...
没本 发表于 2010-07-02 10:59



    我就等你最后一句话呢  那么找你的意思,读文件应该着这么找写了?
  1. int len = 100;//文件实际长度,已知
  2. int r = 0;
  3. while ( len>0 )
  4. {
  5.     r = fread(buf,1,len,fp);
  6.     len-=r;
  7. }
  8. ...
复制代码

论坛徽章:
0
15 [报告]
发表于 2012-11-27 15:50 |只看该作者
我现在集中回复我以前发的SB帖子,我错了,我n年前太菜了,让大家见笑了




这个man写的很清楚了,为啥你就不看呢

论坛徽章:
0
14 [报告]
发表于 2010-07-03 02:08 |只看该作者
本帖最后由 没本 于 2010-07-03 02:11 编辑

如果文件长度100不是已知的话,还要调整fread中的读长度参数为100-total,以免缓冲区溢出。如不如此的话,为缓冲区多分配100字节也是一个好办法。因为文件长度有可能因某种原因改变,例如中病毒。程序员不能假设系统里一切都是按自己设想的存在,因此健壮的程序里必须处理各种意外。不要害怕烦琐而写出有缺陷的程序,给黑客制造攻击机会。

论坛徽章:
0
13 [报告]
发表于 2010-07-03 02:02 |只看该作者
我不知道LZ把我的回帖提前是什么意思,但LZ的循环体明显是有问题的。

  1. int len = 100;//文件实际长度,已知
  2. int r = 0;
  3. while ( len>0 )
  4. {
  5.     r = fread(buf,1,len,fp);
  6.     len-=r;
  7. }
复制代码
注意LZ没有判断返回值r==0的情况,这是程序员常见的问题,往往图方便不愿意写全容错代码。
我的改动意见如下:

  1.   total = 0;
  2.   while( !feof( stream )  && total<100 )
  3.    {
  4.       // Attempt to read in 100 bytes:
  5.       count = fread( buffer+total, sizeof( char ), 100, stream );
  6.       if( ferror( stream ) )      {
  7.          perror( "Read error" );
  8.          break;
  9.       }

  10.       // Total up actual bytes read
  11.       total += count;
  12.    }
复制代码

论坛徽章:
0
12 [报告]
发表于 2010-07-02 19:15 |只看该作者
本帖最后由 聪聪知不道 于 2010-07-02 19:18 编辑

这里用循环读取我觉得不太合适。

首先,我们要弄清我们在做什么:

如果我们要读一个文件并且读完为止,那么我们在读以前是没有必要知道这个文件究竟有多大的,那么这个100从何而来?

如果我们没有要求,就是要读100个字节,那如果本身这个文件就没有100个字节那么长怎么办?循环读取会造成死循环,这是不是我们想要的结果?(如果确定我们就要实现这种效果当然可以这么做,比如说网络编程)


如果我们已知一个文件有超过100个字节长,并且我们无脑的读100字节出来,那这时候实际上fread在读到数据以后只有两种返回值:a.返回-1,表示读取过程中发生异常;b.返回100。fread标准库是不会被信号打断的,标准库实现中已经为我们做好了被信号打断重读。

论坛徽章:
0
11 [报告]
发表于 2010-07-02 15:10 |只看该作者
本帖最后由 marxn 于 2010-07-02 15:24 编辑

如果是磁盘文件就不需要判断。fread在读取磁盘文件时,只有读完了指定的字节数或者:
1、到了文件末尾
2、发生错误
的时候才会出现实际读取的字节数小于指定字节数的现象。

如果是由fdopen打开socket产生的stream,那么确实会出现实际读取的字节数小于指定字节数的现象。

论坛徽章:
0
10 [报告]
发表于 2010-07-02 12:51 |只看该作者
o~~~~~~~~~~~~~~~~~~~~~~~原来如此

论坛徽章:
0
9 [报告]
发表于 2010-07-02 11:59 |只看该作者
是的,还有判断r返回0的情况,要不就死循环了。

论坛徽章:
0
8 [报告]
发表于 2010-07-02 11:07 |只看该作者
以返回的长度为准。如果不足是要再读的。至于这种情况是否发生,和平台以及fread()实现情况有关。你不能假设 ...
没本 发表于 2010-07-02 10:59



    我就等你最后一句话呢  那么找你的意思,读文件应该着这么找写了?
  1. int len = 100;//文件实际长度,已知
  2. int r = 0;
  3. while ( len>0 )
  4. {
  5.     r = fread(buf,1,len,fp);
  6.     len-=r;
  7. }
  8. ...
复制代码

论坛徽章:
0
7 [报告]
发表于 2010-07-02 11:06 |只看该作者
冗余检查是必需的
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP