我从这样的文件中读取:
#include <stdio.h>
int main() {
FILE *fp = fopen("sorted_hits", "r+");
while(!feof(fp)) {
int item_read;
int *buffer = (int *)malloc(sizeof(int));
item_read = fread(buffer, sizeof(int), 1, fp);
if(item_read == 0) {
printf("at file %ld\n", ftell(fp));
perror("read error:");
}
}
}
此文件很大,有时会出现“错误文件描述符”错误。 “ ftell”表示发生错误时文件位置停止。
我不知道为什么有时是这样,这很正常吗?问题出在我的代码还是在硬盘上?如何处理?
perror
将errno
中的所有内容打印为描述性字符串。每当系统调用返回错误时,errno
就会设置为错误代码。但是,如果系统调用不会失败,则errno
不会被修改,并且将继续包含以前包含的所有内容。现在,如果fread
返回0,则意味着出现错误或者您到达文件末尾。在后一种情况下,未设置errno
,并且可能包含之前的任何随机垃圾。
因此,在这种情况下,您可能收到的“错误文件描述符”消息仅表示根本没有错误。您应该检查ferror(fp)
以查看是否发生了错误。
读取文件时,您似乎在混合文本和二进制模式。
[通常,当您使用fread
时,您从二进制文件读取,即fread
读取了一些与缓冲区大小匹配的字节,但是您似乎正在以文本模式(r +)打开文件。 ftell
在以文本模式打开的文件上无法可靠工作,因为换行符与其他字符的区别。
改为以二进制模式打开文件(未翻译):
FILE *fp = fopen("sorted_hits", "rb+");
如果这确实是您的循环的样子,我猜您可能会收到或多或少的虚假错误,因为您的进程正快用完内存,因为您的循环泄漏得非常严重(每次调用malloc
循环,但在任何地方都没有匹配调用free
。
[(但几乎总是不正确的)使用while (!feof(fp))
时,您也有可能遇到一个小问题(但可能性要小得多。
您对printf
的全部操作也给出了未定义的行为,因为您不匹配转换和类型(尽管在许多当前系统上,这无关紧要,因为long和int的大小相同)。
解决这些问题可能会或可能不会消除您所观察到的问题,但是至少如果仍然看到此问题,您将缩小可能引起问题的可能性。
int main() {
FILE *fp = fopen("sorted_hits", "r+");
int buffer;
while(0 != fread(&buffer, sizeof(int), 1, fp))
; // read file but ignore contents.
if (ferror(fp)) {
printf("At file: %ld\n", ftell(fp));
perror("read error: ");
}
}