fread大概只能读10k

来源:百度知道 编辑:UC知道 时间:2024/06/02 04:01:14
从一个文件中把数据复制到另外一个文件中,我的代码如下:
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函数来实现。

错误原因:
你用文本方式打开了二进制文件

文本方式读取二进制数据, 可能在文件结束之前将某段数据判定为文件末尾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+" );