为什么fread有时遇到“Bad file descriptor”?

时间:2012-02-22 06:28:20

标签: c file stream fread

我从这样的文件中读到:

#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”表示发生错误时文件位置停止。

我不知道为什么它“有时”,这是正常的吗?问题出在我的代码或硬盘中吗?如何处理?

3 个答案:

答案 0 :(得分:5)

perror打印errno中的任何内容作为描述性字符串。只要系统调用返回错误,errno就会被设置为错误代码。但是,如果系统调用没有失败,errno不会被修改,并将继续包含之前包含的内容。现在,如果fread返回0,则表示存在错误或者您到达文件末尾。在后一种情况下,errno未设置,可能包含之前的任何随机垃圾。

因此,在这种情况下,您获得的“错误文件描述符”消息可能只意味着根本没有错误。您应该检查ferror(fp)以查看是否发生了错误。

答案 1 :(得分:1)

在阅读文件时,您似乎混合了文本和二进制模式。

通常当您使用fread时,您从二进制文件中读取,即fread读取与缓冲区大小匹配的字节数,但您似乎在文本模式(r +)中打开文件。 ftell对文本模式下打开的文件无法可靠地工作,因为换行的处理方式与其他字符不同。

以二进制模式打开文件(未翻译)而不是

FILE *fp = fopen("sorted_hits", "rb+");

答案 2 :(得分:0)

如果这真的是你的循环的样子,我的猜测是你可能会得到一个或多或少的虚假错误,因为你的进程正在耗尽内存,因为你的循环正在如此糟糕地泄漏(调用{{1循环的每次迭代,但在任何地方都没有与malloc的匹配调用。)

free的(常见但几乎总是不正确的)使用中遇到一个小问题也是可能的(但不太可能)。

你的所有while (!feof(fp))也给出了未定义的行为,因为你的转换和类型不匹配(虽然在许多当前系统上它是无关紧要的,因为long和int的大小相同)。

修复那些可能会或可能不会消除您观察到的问题,但至少如果您仍然看到它,您将缩小可能导致问题的可能性。

printf