feof() 在未达到 EOF 时返回 true

feof() returning true when EOF is not reached

提问人:Daniel Sloof 提问时间:12/15/2010 最后编辑:Daniel Sloof 更新时间:12/15/2010 访问量:821

问:

我正在尝试从特定偏移量(简化版本)的文件中读取:

typedef unsigned char u8;
FILE *data_fp = fopen("C:\\some_file.dat", "r");
fseek(data_fp, 0x004d0a68, SEEK_SET); // move filepointer to offset
u8 *data = new u8[0x3F0];
fread(data, 0x3F0, 1, data_fp);
delete[] data;
fclose(data_fp);

问题变成了,该数据将不包含 1008 字节,而是 529(似乎是随机的)。当它达到 529 字节时,对 feof(data_fp) 的调用将开始返回 true。

我还尝试读取较小的块(一次 8 个字节),但当它还没有出现时,它看起来就像正在击中 EOF。

在十六进制编辑器中简单查看一下就会发现还有很多字节

C++ FOPEN FEOF

评论

0赞 Daniel Sloof 12/15/2010
@pmg,使用 malloc/free 并不能解决我的问题,但适合自己:)
1赞 pmg 12/15/2010
在 C 中(我不知道 C++)我会尝试以二进制模式打开文件
0赞 Daniel Sloof 12/15/2010
@pmg,该死的!就是这么简单......请创建一个答案,我会接受的。
0赞 Eugen Constantin Dinca 12/15/2010
偏移量 0x004d0a68 + 529 是什么?
1赞 pmg 12/15/2010
+1 代表 xvi。你也用 vi 编辑吗?

答:

1赞 unwind 12/15/2010 #1

文件是否由其他应用程序并行写入?也许存在争用条件,因此文件在读取停止的位置结束,当读取正在运行时,但稍后当您检查它时,其余部分已被写入。这也可以解释随机性。

评论

0赞 Daniel Sloof 12/15/2010
不!它正在被另一个应用程序读取,但关闭它甚至复制文件并更改路径会给我相同的结果......奇怪的是,随机数(529)每次都是一样的
5赞 pmg 12/15/2010 #2

像您一样,以文本模式打开文件会使库将某些文件内容转换为其他内容,从而可能触发不必要的 EOF 或错误的偏移量计算。

通过将“b”选项传递给 fopen 调用,以二进制模式打开文件

fopen(filename, "rb");
1赞 Milan Babuškov 12/15/2010 #3

也许这是文本文件和二进制文件之间的区别。如果您使用的是 Windows,换行符是 CRLF,即文件中的两个字符,但在读取时仅转换为一个字符。尝试使用 fopen(..., “rb”)

0赞 Dov 12/15/2010 #4

我在工作中看不到您的链接,但是如果您的计算机声称不再存在字节,我倾向于相信它。为什么不打印文件的大小,而不是在十六进制编辑器中手动操作?

此外,您最好使用 2 级 I/O,因为 f 调用是古老的 C 丑陋,并且您正在使用 C++,因为您有新的。

int fh =open(filename, O_RDONLY);
struct stat s;
fstat(fh, s);
cout << "size=" << hex << s.st_size << "\n";

现在使用 2 级 I/O 调用进行查找和读取,无论如何都更快,让我们看看文件的实际大小是多少。

评论

0赞 Sergei Tachenov 12/15/2010
在大多数情况下,f-call 速度更快,因为它们是缓冲的,而 low-level 是无缓冲的。不过,在这种情况下,这并不重要,因为只有一次读取。
0赞 Dov 12/15/2010
如果你想要速度,不要使用旧的、粗糙的 C api,里面有一层又一层的垃圾。如果你正在做大量的读取,你需要一个高性能的缓冲类,是的。