提问人:Daniel Sloof 提问时间:12/15/2010 最后编辑:Daniel Sloof 更新时间:12/15/2010 访问量:821
feof() 在未达到 EOF 时返回 true
feof() returning true when EOF is not reached
问:
我正在尝试从特定偏移量(简化版本)的文件中读取:
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。
在十六进制编辑器中简单查看一下就会发现还有很多字节。
答:
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,里面有一层又一层的垃圾。如果你正在做大量的读取,你需要一个高性能的缓冲类,是的。
下一个:php - feof 错误
评论