我在linux上遇到了一些关于fgets()的问题。fgets正在从已关闭的filedescriptor返回数据。如果文件被关闭,我期望它返回EOF。我能够想出我的问题的一个简化版本。
int main()
{
int i=0, j;
FILE *FD;
char p[128];
FD = fopen("junk", "r");
while(fgets(p, sizeof(p), FD))
{
close(fileno(FD));
printf("lineno=%d\n", i++);
}
return 0;
}
我希望它只打印一行。是否有解决此问题的方法?
更新:正如下面有人回答的那样,fgets正在缓冲文件并返回数据,即使在FD关闭之后也是如此。它正在缓冲4kB的数据。如果文件大小超过4k,则在读取4KB后出现EOF,打印停止。否则,如果文件小于4k,它会一直打印到文件的末尾。
发布于 2011-09-08 01:53:17
正如其他人所说,close(fileno(FD));
不是一个好主意。如果这样做,相同的文件描述符可能会被另一个文件重用,而fgets
会突然读取该fd。这对于多线程应用程序来说尤其可能。
此外,fgets也是缓冲的。它可能在第一次调用时从文件中读取了大量数据,随后的调用只会从缓冲区返回更多数据。
相反,可以这样做:
int main(void)
{
int i=0, j;
FILE *FD;
char p[128];
FD = fopen("junk", "r");
while(FD && fgets(p, sizeof(p), FD))
{
fclose(FD);
FD = NULL;
printf("lineno=%d\n", i++);
}
return 0;
}
发布于 2011-09-08 01:32:51
在已关闭的文件上调用fgets()具有未定义的行为。换句话说,不能保证返回EOF。
发布于 2011-09-08 01:34:16
在关闭文件描述符之后使用它可能会导致不可预测/未定义的行为。您可能应该避免这样做。
在发布的示例中可能发生的情况是,流被打开并被读取。读取数据可能会将更多数据放入底层流中。因此,即使底层文件描述符已关闭,流的句柄仍将包含更多要读取的数据。同样,这可能是不可预测的。
https://stackoverflow.com/questions/7338032
复制相似问题