C文件流操作的fread和fseek

近日写程序,使用了一个读取二进制文件的操作,函数的声明如下:
//功能:读取磁盘的一个4k大小的文件到内存中,作为一个内存页的数据。如果文件不足4k,则依然在内存中开辟4k的空间进行储存。
void DiskToMemory(PagesManager *p_mgr, PageType col_type, FILE *infile);


但是当在这个函数中调用fread时,总是出问题,文件根本没有被读进内存中:
//第1、2个参数为实现特定功能而设置的,前者只是一个void*型的内存地址,SizeOf[col_type]此处值为4
//注意到第3个参数使用了一个GetFileSize(infile)函数,功能是获取文件的大小(文件可能<4k)
fread(p_mgr->Pages[ p_mgr->CurrentPage[col_type] ], SizeOf[col_type], GetFileSize(infile) / SizeOf[col_type], infile);


使用了一天的时间来查错:
先看文件打开是否失败了,
再看是否对文件是否有读的权限,
然后查看fread返回的值,发现fread每次都是返回0(此时才判断出是fread的问题)。


在网上查找相关资料,发现fread返回值为0有两种情况:一种是文件结尾,一种是发生错误。
那到底是错误还是文件结尾呢?我在fread执行前和执行后都使用feof判断文件流的情况,发现执行前不是文件结尾,执行后则是文件结尾。
乍一看那应该是发生了错误。那哪里发生了错误呢?因为是在linux下用文本编辑器编程,所以每次都只能乖乖地使用printf函数监测各个变量的值的变化,甚至还尝试过使用常数去代替一些变量,问题依然存在。


事已至此本来也想放弃了,甚至开始怀疑自己linux下的编译器是不是版本太老了之类。


事情出现转机是在我尝试在本函数内使用fopen打开文件流而不是从别的函数传递一个文件流指针的时候,猛然发现,其实问题就出现在这个文件流指针上,但是为什么呢?
我开始寻找整个工程文件跟文件流操作有关的函数,此时我看到了int GetFileSize(FILE *infile) 函数,其定义是:
int GetFileSize(FILE* file) {
fseek(file, 0L, SEEK_END);
return ftell(file);
}
这段代码当时是从网上的一个教程那里学来的,没有理解透彻。搜了一下ftell跟fseek文件,发现问题出现在fseek上!!在C++Reference它的功能解释是:
//Sets the position indicator associated with the stream to a new position.
//For streams open in binary mode, the new position is defined by adding offset to a reference position specified by origin.

int fseek(FILE *stream, long int offset, int origin);
即将文件流指针指向文件流中origin+offset的位置。而在我的工程文件的int GetFileSize(FILE* file)函数中,fseek(file, 0L, SEEK_END)执行完后,文件流指针就已经指向了文件尾了,此时fread当然不成功了,而且使用feof还无法判断出这个错误!


后续:更加深入地了解fread的功能之后,发现判断读入文件的大小完全就是多次一举。因为fread在遇到文件尾的时候就会自动结束读入,返回读取到的数据的个数,如此一来何必大费周章去判断文件的实际大小呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值