为什么 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”表示发生错误时文件位置停止。
我不知道为什么是“有时”,这正常吗?问题出在我的代码还是硬盘上?这要怎么处理呢?
I am read from a file like this:
#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:");
}
}
}
This file is big and I got the "Bad file descriptor" error sometimes. "ftell" indicates that the file position stopped when error occurred.
I don't know why it is "sometimes", is that normal? does the problem lie in my code or in my hard disk? How to handle this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
perror
将errno
中的内容打印为描述性字符串。每当系统调用返回错误时,errno
就会设置为错误代码。但是,如果系统调用没有失败,则 errno 不会被修改,并且将继续包含之前包含的内容。现在,如果fread
返回 0,则意味着出现错误或已到达文件末尾。在后一种情况下,errno
未设置,并且可能包含之前的任何随机垃圾。因此,在这种情况下,您收到的“错误文件描述符”消息可能仅意味着根本没有错误。您应该检查
ferror(fp)
以查看是否发生错误。perror
prints whatever is inerrno
as a descriptive string.errno
gets set to an error code whenever a system call has an error return. But, if a system call DOESN'T fail,errno
doesn't get modified and will continue to contain whatever it contained before. Now iffread
returns 0, that means that either there was an error OR you reached the end of the file. In the latter case,errno
is not set and might contain any random garbage from before.So in this case, the "Bad file descriptor" message you're getting probably just means there hasn't been an error at all. You should be checking
ferror(fp)
to see if an error has occurred.读取文件时您似乎混合了文本和二进制模式。
通常,当您使用
fread
时,您从二进制文件中读取,即fread
读取与缓冲区大小匹配的多个字节,但您似乎以文本模式(r+)打开文件。ftell
在以文本模式打开的文件上无法可靠地工作,因为换行符的处理方式与其他字符不同。以二进制模式(未翻译)打开文件:
You seem to be mixing text and binary modes when reading the file.
Normally when you use
fread
you read from a binary file i.e.fread
reads a number of bytes matching the buffer size but you seem to be opening the file in text mode (r+).ftell
doesn't work reliably on files opened in text mode because newlines are treated differently than other characters.Open the file in binary mode (untranslated) instead:
如果这确实是您的循环的样子,我的猜测是您可能会遇到或多或少的虚假错误,因为您的进程刚刚耗尽内存,因为您的循环严重泄漏内存(调用
malloc 循环的每次迭代,但在任何地方都没有对
free
的匹配调用)。您也有可能(但不太可能)因使用
while (!feof(fp))
(常见但几乎总是不正确)而遇到一些小问题。您对 printf 的所有操作也会给出未定义的行为,因为您的转换和类型不匹配(尽管在许多当前系统上这是不相关的,因为 long 和 int 的大小相同)。
解决这些问题可能会也可能不会消除您所观察到的问题,但至少如果您仍然看到它,您将缩小导致问题的可能性。
If that's really what your loop looks like, my guess would be that you're probably getting a more or less spurious error because your process is just running out of memory because your loop is leaking it so badly (calling
malloc
every iteration of your loop, but no matching call tofree
anywhere).It's also possible (but a lot less likely) that you're running into a little problem from your (common but nearly always incorrect) use of
while (!feof(fp))
.Your all to
printf
also gives undefined behavior because you've mismatched the conversion and the type (though on many current systems it's irrelevant because long and int are the same size).Fixing those may or may not remove the problem you've observed, but at least if you still see it, you'll have narrowed down the possibilities of what may be causing the problem.