关于fread的问答 matlab的fread函数

从一个文件中把数据复制到另外一个文件中,我的代码如下:
while (i<38016)//文件大小为38016字节,i(unsigned int),temp(char)
{
fread(&temp,1,1,fyuv);
fwrite(&temp,1,1,fyuv1);
i++;
}
结果文件有38k,其中前面大概10k是正确的(与源文件进行二进制代码比对),后面的约28k就重复前面10k的最后一个字节,也就是后面28k所有字节完全一样。
若把代码换成:
do
{
i=fread(&temp,1,1,fyuv);
fwrite(&temp,i,1,fyuv1);
}while(i>0);
则得到的结果文件大概只有10k,且这10k与源文件的前10k一样(比对二进制代码),但是后28k就没有了。
请问我该怎么做才是正确的呢?
ps:如果用CFile类则可以正确地复制文件,但是我现在想用fread函数来实现。
正在发表回答,请稍候…… 您输入的内容将会在您成功登录之后自动发表。 回答 8976541 2009-09-26 09:31:23 错误原因:
你用文本方式打开了二进制文件

文本方式读取二进制数据, 可能在文件结束之前将某段数据判定为文件末尾EOF, 所以结束读取( 举个例子, 比如遇到 0x00 0x00 0xff 0xff, 则文本方式方式的文件流, 认为已经到文件末尾, 不能读取)

你这个38016的文件, 大概在10k左右有段数据和文件结束标志格式相同, 文本方式读取到10k左右就认为文件结束了( 真正的文本文件, 结束标志可能在磁盘簇的剩余空间中 )

所以第一种方式:
固定读取38016次, 每次往新文件中写一个字节; 前10k次能读取到内容, fread返回值是1, 这样写过去的一字节就是读取的字节; 后28k因为读取失败, fread返回值为0, 这样temp的内容就不会被改写, 仍然是最后一次成功读取的值, 但因为是写次数固定, 所以后28k就重复写过去;
后一种方式:
根据fread的返回值来判定文件结束, 这是正确的方法; 所以读取到10k后, 返回值为0, 表示无效, 文件结束, 所以只复制了10k内容

CFile只支持二进读写, 所以你的结果是正确的( CFile用CFile::typeText格式会报错; CStdioFile才能文本读写)
用fopen返回的FILE, 如果读取的时候没有加b( 比如"r"), 则默认的是文本格式; 所以请用"rb"来读取二进制文件, 用"wb"写二进制文件; 当然如果只是复制文件的话, 纯二进制读写没有问题

下面是楼主要的效果, 是一个字节读写的
#include <stdio.h>
int main()
{
FILE *pFileS = fopen( "s.rar", "rb" );
if( ! pFileS )
return 1;
FILE *pFileD = fopen( "d.rar", "wb+" );
关于fread的问答 matlab的fread函数

unsigned char bTemp;
while( fread( &bTemp, sizeof(unsigned char), 1, pFileS) )
fwrite( &bTemp, sizeof(unsigned char), 1, pFileD );

fclose( pFileS ), fclose( pFileD );
return 0;
}
其实一个字节读写的话, 用fgetc和fputc就可以了, 当然还是得以二进制方式打开

另外单字节读写速度太慢; 系统中复制文件都是整块读写的, 设置缓冲大小
比如
#include <stdio.h>
int main()
{
FILE *pFileS = fopen( "s.rar", "rb" );
if( ! pFileS )
return 1;
FILE *pFileD = fopen( "d.rar", "wb" );

unsigned char buffer[ 4 * 1024 ];
int nRead;
while( nRead = fread( buffer, sizeof(unsigned char), sizeof(buffer), pFileS ) )
fwrite( buffer, sizeof(unsigned char), nRead, pFileD );

fclose( pFileS ), fclose( pFileD );
return 0;
}

另外, fread单次读取的总字节数有限制, 也就是说缓冲有上限; 只能通过提高次数来读取大文件; 在这方面, 用API如ReadFile或者调用了这些API的封装类就好得多; 当然, 次数多对电脑来说不是问题呵呵

附:
至于文本方式不能完全读取, 而二进制方式能的原因-
文本方式读取文件, 最主要的用处是一次读取一整句( 以换行符'n', 即二进制的换行标志"rn"结束 ), 方便用于特殊用处ReadString、fscanf(...,"%s",...)之类, 每次读取的内容长度是不定的; 而二进制读取方式Read、fread等, 都是读取固定长度
所以文本方式读取对EOF的判定, 是一个文件尾结束标志, 如果是文本文件, 则这个文件尾肯定不会出现在文件内容中( 因为是不可打印字符构成的结束标志, 人可读的文本文件不会包括它 ), 这样以结束标志为文件尾则是可以的; 二进制文件内容可以是任意字节, 如果把它当文本文件来读, 以文件尾为结束, 当然可能出现把文件内容判定为文件尾的情况;
二进制读取方式由于每次读取固定字节, 所以只需要用总文件长度( 这个数值是系统管理的数值, 不是计算得出来的 )减去每次读取的长度( 或根据Seek的位置计算长度 ), 就可以知道是否到文件尾, 不需要定义结束标志; 所以用二进制方式打开任何文件都是合理的

  

爱华网本文地址 » http://www.aihuau.com/a/25101011/91772.html

更多阅读

关于安全的手抄报图片 小学生手抄报图片大全

关于安全的手抄报图片——简介整理了些关于安全的手抄报图片,供大家欣赏。关于安全的手抄报图片——关于安全的手抄报图片关于安全的手抄报图片 1、安全是生命之本,安全永在我身边。放学回家不要在外面逗留,直接回家关于安全的手抄报

十大经典的关于母亲的电影 八卦神探国语

母亲节就要到了,整理出十大关于母亲的电影,祝全天下的母亲节日快乐,永远年轻。健康。十大经典的关于母亲的电影——步骤/方法十大经典的关于母亲的电影 1、妈妈再爱我一次应该说从上世纪80年代走来的观众,大抵都还记得记忆里的那一次集

关于爱的六个谎言 武志红爱的八个谎言

关于爱的六个谎言武志红谎言(一):没有父母不爱自己的孩子这是天下无数谎言中的No.1。这个谎言如此绝对,以至于很容易被驳倒。实际上,我们只需要找出一个例外就可以驳倒这个断言,而这样的“例外”又实在是太多

名言警句系列之十一关于公平的名言警句 名言警句大全

关于公平的名言警句符同权1.政在去私,私不去则公道亡。(傅玄)2.一心可以兴邦,一心可以丧邦,只在公私之间尔。(朱熹)3.治身莫先于孝,治国莫先于公。(苏轼)4.大明无私照,至公无私亲。(张蕴古)5.公生明,偏生暗。(荀子)6.人心公则如烛,四方上下,无所不照

在中国,关于大麻的刑罚 中国古代刑罚大全

最近关于各种大麻的的新闻不断,昨儿看到陈同学被入刑事罪,顺手查了下在中华人民共和国关于大麻的刑罚,发现原来我国的刑法相当地科学。跟毒品相关的行为,主要分为三类,自用,教唆收容他人,运输贩卖,牵扯到未成年人的,都要从重处罚。在这三类

声明:《关于fread的问答 matlab的fread函数》为网友歲月偏移分享!如侵犯到您的合法权益请联系我们删除