fread读取二进制文件,fwrite只能用于二进制文件
大家好,今天小编来为大家解答fread读取二进制文件这个问题,fwrite只能用于二进制文件很多人还不知道,现在让我们一起来看看吧!
关于c语言读取二进制文件fread问题
这个很正常,这是操作系统的缓存(cache)在起作用。
缓存:为了解决CPU速度和内存速度的速度差异而产生(CPU运算速度比内存快的多)
当程序需要读取某个文件时,实际就是把数据读入内存由CPU运算,CPU首先去缓存中找寻,查找不到就会到内存中去读取同时复制到缓存中以便下次访问,这个时候速度自然很慢,当你第二次读取该文件时,缓存中已经存在,CPU再次访问这些数据就会变的非常快。
这是和系统读取数据的方式有关的,并不是因为某个函数效率低的原因,比较明显的:
你在某个磁盘下搜索某一个文件名,第一次会比较慢,第二次就会快很多,原因就是第二次CPU需要处理的数据已经存在缓存中,处理时效率会非常高。
Matlab中如何实现二进制文件的读写
1)写二进制文件
fwrite函数按照指定的数据精度将矩阵中的元素写入到文件中。其调用格式为: COUNT=fwrite(fid,A,'precision')
说明:其中COUNT返回所写的数据元素个数(可缺省),fid为文件句柄,A用来存放写入文件的数据,precision代表数据精度,常用的数据精度有:char、uchar、int、long、float、double等。缺省数据精度为uchar,即无符号字符格式。例6.8将一个二进制矩阵存入磁盘文件中。>> a=[1 2 3 4 5 6 7 8 9];
>> fid=fopen('d:\test.bin','wb')%以二进制数据写入方式打开文件 fid=
3%其值大于0,表示打开成功>> fwrite(fid,a,'double') ans=
9%表示写入了9个数据>> fclose(fid) ans=
0%表示关闭成功
2)读二进制文件
fread函数可以读取二进制文件的数据,并将数据存入矩阵。其调用格式为: [A,COUNT]=fread(fid,size,'precision')
说明:其中A是用于存放读取数据的矩阵、COUNT是返回所读取的数据元素个数、fid为文件句柄、size为可选项,若不选用则读取整个文件内容;若选用则它的值可以是下列值:N(读取N个元素到一个列向量)、inf(读取整个文件)、[M,N](读数据到M×N的矩阵中,数据按列存放)。precision用于控制所写数据的精度,其形式与fwrite函数相同。
%写一维数据至数据文件 n=0:pi/10:4*pi; y=sin(n);
fip=fopen('C:\binary3.bin','wb'); fwrite(fip,Pxx,'double'); fclose(fip);
fread大概只能读10k
错误原因:
你用文本方式打开了二进制文件
文本方式读取二进制数据,可能在文件结束之前将某段数据判定为文件末尾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+");
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',即二进制的换行标志"\r\n"结束),方便用于特殊用处ReadString、fscanf(...,"%s",...)之类,每次读取的内容长度是不定的;而二进制读取方式Read、fread等,都是读取固定长度
所以文本方式读取对EOF的判定,是一个文件尾结束标志,如果是文本文件,则这个文件尾肯定不会出现在文件内容中(因为是不可打印字符构成的结束标志,人可读的文本文件不会包括它),这样以结束标志为文件尾则是可以的;二进制文件内容可以是任意字节,如果把它当文本文件来读,以文件尾为结束,当然可能出现把文件内容判定为文件尾的情况;
二进制读取方式由于每次读取固定字节,所以只需要用总文件长度(这个数值是系统管理的数值,不是计算得出来的)减去每次读取的长度(或根据Seek的位置计算长度),就可以知道是否到文件尾,不需要定义结束标志;所以用二进制方式打开任何文件都是合理的
END,本文到此结束,如果可以帮助到大家,还望关注本站哦!