在 C 中关闭文件

Close file in C

在 Linux 下,我使用此代码重定向文件上的 stdout 和 stderr,如代码所示,文件是使用 fopen(f) 打开的,并使用 close(fd) 关闭的。

int         fd;
FILE        *f;   

f = fopen("test.txt", "rb+");

fd = fileno(f);
dup2(fd,STDOUT_FILENO);
dup2(fd,STDERR_FILENO);
close(fd);

我的问题是 close(fd) 语句是否关闭所有文件描述符,或者是否有必要使用 fclose(f)还有吗?

C FILE* 流在内部使用缓冲 I/O。 fclose() 刷新此缓冲区,然后在 OS 级别关闭文件描述符。 close()'ing FILE* 流可能不会刷新此内部缓冲区,您可能会丢失数据。所以对于 C 流总是使用 C fxxx() 函数。

规则是关闭最外层。这里 f 指向的 FILE 对象包含 fd 文件句柄,但也包含内部数据,如可能的缓冲区和指向它的各种指针。

当你使用close(fd)时,你释放了文件相关的内核结构,但是标准库提供的所有数据结构都没有被释放。另一方面,fclose(f) 将在内部关闭 fd 文件句柄,但它也会释放由 fopen.

分配的所有资源

TL/DR:如果你使用fd= open(...);打开一个文件,你应该使用close(fd);关闭它,但是如果你使用f = fopen(...);,那么你应该使用fclose(f);.

正如其他答案中已经指出的那样,您应该使用 fclose(f); 而不是 close(fd);

My question is whether the close(fd) statement closes all file descriptors [...]

不,它不会关闭所有文件描述符。文件描述符 STDOUT_FILENOSTDERR_FILENO 仍将保持打开状态,并且现在将引用打开的文件 test.txt。但是,这些文件描述符可能不应该关闭,因为 STDOUT_FILENOSTDERR_FILENO 在程序结束之前保持有效是一种良好的编程习惯。它们将在进程终止时由内核自动关闭。