如何每次从二进制文件中读取定长的内容?

xiaojunjun1202 2011-07-23 06:53:34
如何每次从二进制文件中读取定长的内容?利用FILE类如何判断是否是最后一个定长内容?
另外,定义FILE *F,如果flose(f)关闭后,f=NULL吗?

这是我读文件的代码(一个Timer里头),每次到了文件的最后一个定长内容就出问题。FilePointPos 文件指针的位置是对的,也就是文件的总字节数。
但是这时fread(pPerFrmDataInFile,sizeof(WORD),nBlockSize,f)返回的是0.
		if (f)
{
long FilePointPos = ftell(f); //测试文件指针,可以删除
if( !feof( f ))
{
//long offset = 0;
//fseek(f, O,SEEK_END);
//long FilePointPos = ftell(f); //测试文件指针,可以删除

if(fread(pPerFrmDataInFile,sizeof(WORD),nBlockSize,f) != nBlockSize) //fix xiaojun 2011年7月20日15:39:03//nBlockSize 0
{
//::AfxMessageBox("读取文件失败!请检查文件名及参数信息!");
if(fread(pPerFrmDataInFile,sizeof(WORD),nBlockSize,f) < nBlockSize)
{
if (f)
{
if(fclose(f))//add by xiaojun 2011年7月20日11:24:40
{
MessageBox(_T("文件关闭失败!"));
}
free(f);
}
KillTimer(1);
}


}
else
{
memcpy(pPerFrmLoadData, pPerFrmDataInFile, nBlockSize*sizeof(WORD)); // add by xiaojun 2011年7月20日
}
}
else
{
if (f)
{
if(fclose(f))//add by xiaojun 2011年7月20日11:24:40
{
MessageBox(_T("文件关闭失败!"));
}
}
}
}


打开文件的代码:
	FileNameForPlay = lpszOpenFile.GetPathName().GetBuffer(0);
// 打开文件
//FILE* f; //add by xiaojun 2011年7月20日11:08:24
if (f == (FILE*)NULL)
{
f = fopen(FileNameForPlay,"r+b");
if(( f == (FILE*)NULL ))//fopen_s( &f, FileNameForPlay, "r + b" )
{
MessageBox(_T("打开回放文件错误!"));
}
// f = fopen(lpszOpenFile.GetPathName().GetBuffer(0),"r+b");
}
...全文
303 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaojunjun1202 2011-08-04
  • 打赏
  • 举报
回复
自己解决了,散分~~~
jsyren 2011-07-23
  • 打赏
  • 举报
回复
ding
zgl7903 2011-07-23
  • 打赏
  • 举报
回复
1: 打开文件是否有读取的权限 ("rb") ?
2: 检查文件长度是否正确 ?
3: fread(pPerFrmDataInFile, 1, sizeof(WORD)* nBlockSize,f) 看能读会多少长度 ?
schlafenhamster 2011-07-23
  • 打赏
  • 举报
回复
二进制文件中读取定长
使用随机文件,不要使用顺序文件。
呔妖怪来嘛 2011-07-23
  • 打赏
  • 举报
回复

if(fclose(f))//add by xiaojun 2011年7月20日11:24:40
{
MessageBox(_T("文件关闭失败!"));
}
if (f == NULL)
{
MessageBox(_T("文件关闭成功!"));
}


fclose(f)之后f是不为空的
if (f == NULL)
{
MessageBox(_T("文件关闭成功!"));
}
而且这个根本就没用
上一个没显示(_T("文件关闭失败!"));
自然就成功了
xiaojunjun1202 2011-07-23
  • 打赏
  • 举报
回复
To ouyh12345
可能是我问题没描述清楚,继续补充

但是这时fread(pPerFrmDataInFile,sizeof(WORD),nBlockSize,f)返回的是0.
此时会进入
if(fclose(f))//add by xiaojun 2011年7月20日11:24:40
{
MessageBox(_T("文件关闭失败!"));
}
此时调用了fclose(f)后,f=NULL吗?因为我后面会打开改文件,想利用f来判断。我调试的时候发现调用了
fclose(f)后,f并没有为NULL,奇怪啊~,好像只是f->_ptr = 0x00;
f->_base = 0x00; f->_tmpfname = 0x00;
具体操作:if(fclose(f))//add by xiaojun 2011年7月20日11:24:40
{
MessageBox(_T("文件关闭失败!"));
}
if (f == NULL)
{
MessageBox(_T("文件关闭成功!"));
}
代码MessageBox(_T("文件关闭成功!")未必执行。
xiaojunjun1202 2011-07-23
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 xiaohuh421 的回复:]
如果flose(f)后, f 不为空,那我第二次打开同样的文件,我该怎么判断?
我现在是这么判断的
if (f == (FILE*)NULL)
{
f = fopen(FileNameForPlay,"r+b");
}


你可以在每个fclose后加上一句 f=NULL;强制把这个文件指针写成为,实际上也应该这样做.


还有
if(fread……
[/Quote]


是的,说的很对,确实不需要两次读的
if(fread(pPerFrmDataInFile,sizeof(WORD),nBlockSize,f) < nBlockSiz)
加上这句的本意我是想判断一下 fread(pPerFrmDataInFile,sizeof(WORD),nBlockSize,f)的返回值是否小于 nBlockSiz.
这里应该用一个变量来接收,然后再与nBlockSiz比较,但这里又会有个问题
变量初始化为0,如果第一次读取文件时,文件恰好为空........让我想想,没想清楚
ouyh12345 2011-07-23
  • 打赏
  • 举报
回复
另外,定义FILE *F,如果flose(f)关闭后,f=NULL吗?
当然不是,得f=NULL;
fread(pPerFrmDataInFile,sizeof(WORD),nBlockSize,f)
一次读的长度是sizeof(WORD) * nBlockSize
xiaohuh421 2011-07-23
  • 打赏
  • 举报
回复
如果flose(f)后, f 不为空,那我第二次打开同样的文件,我该怎么判断?
我现在是这么判断的
if (f == (FILE*)NULL)
{
f = fopen(FileNameForPlay,"r+b");
}


你可以在每个fclose后加上一句 f=NULL;强制把这个文件指针写成为,实际上也应该这样做.


还有
if(fread(pPerFrmDataInFile,sizeof(WORD),nBlockSize,f) != nBlockSize) //fix xiaojun 2011年7月20日15:39:03//nBlockSize 0
{
//::AfxMessageBox("读取文件失败!请检查文件名及参数信息!");
if(fread(pPerFrmDataInFile,sizeof(WORD),nBlockSize,f) < nBlockSize)

你这个地方连续调用两次读,我不知道你目的是什么.
不过提醒下.....因为每次读写后,文件指针都什么自动后移,如果正好你第一次是读取最后一个定长,并且没有nBlockSize,你再想读取就不行了,因为前一个fread之后,文件指针已经指向文件的结尾了,第二次fread必然是错的.
呔妖怪来嘛 2011-07-23
  • 打赏
  • 举报
回复

if(fclose(f))//add by xiaojun 2011年7月20日11:24:40
{
MessageBox(_T("文件关闭失败!"));
}

f = NULL;

xiaojunjun1202 2011-07-23
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 hezhe1008 的回复:]
C/C++ code


if(fclose(f))//add by xiaojun 2011年7月20日11:24:40
{
MessageBox(_T("文件关闭失败!"));
}
if (f == NULL)
{
MessageBox(_T("文件关闭成功!"));
}



fclose(f)之后f是不为空的
if (f == NULL)
{
……
[/Quote]


如果flose(f)后, f 不为空,那我第二次打开同样的文件,我该怎么判断?
我现在是这么判断的
if (f == (FILE*)NULL) //这句如何写?
{
f = fopen(FileNameForPlay,"r+b");
}
我现在的折中的办法就是在flose(f)成功后,加一句f = NULL;是否有其他办法?
xiaojunjun1202 2011-07-23
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 zgl7903 的回复:]
1: 打开文件是否有读取的权限 ("rb") ?
2: 检查文件长度是否正确 ?
3: fread(pPerFrmDataInFile, 1, sizeof(WORD)* nBlockSize,f) 看能读会多少长度 ?
[/Quote]


1、有权限
2、长度正确
3、每次读取的长度一致

如果flose(f)后, f 不为空,那我第二次打开同样的文件,我该怎么判断?
我现在是这么判断的
if (f == (FILE*)NULL)
{
f = fopen(FileNameForPlay,"r+b");
}

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧