为什么必须使用close()关闭文件?

为什么必须使用close()关闭文件?,c,operating-system,C,Operating System,我正在学习一些文件函数,因此有一个疑问 我很好奇为什么需要调用close()来关闭文件?如果我在读/写文件后没有调用close(),会发生什么情况?如果我确实调用了close(),我还可以使用文件描述符吗?如果不关闭为读取而打开的文件,它可能会被阻止并发写入。 如果不关闭为写入而打开的文件,可能会丢失操作系统保存在缓冲区中的最后写入的数据 并且永远不要使用已关闭文件的描述符。这是没有道理的 如果文件后面有任何类型的缓冲,而您不调用close,则可能会丢失数据 如果操作系统的资源有限(例如打开的

我正在学习一些文件函数,因此有一个疑问


我很好奇为什么需要调用
close()
来关闭文件?如果我在读/写文件后没有调用
close()
,会发生什么情况?如果我确实调用了
close()
,我还可以使用文件描述符吗?

如果不关闭为读取而打开的文件,它可能会被阻止并发写入。 如果不关闭为写入而打开的文件,可能会丢失操作系统保存在缓冲区中的最后写入的数据

并且永远不要使用已关闭文件的描述符。这是没有道理的

  • 如果文件后面有任何类型的缓冲,而您不调用close,则可能会丢失数据

  • 如果操作系统的资源有限(例如打开的文件数量),那么不关闭文件就是在浪费系统资源

  • 一旦文件被关闭,使用描述符在最好的情况下是没有意义的,在最坏的情况下是巨大的bug(有点像释放后使用内存)


当您使用write()系统调用写入文件时,它不会立即写入文件。因此,在您的操作之后,您必须调用close(),以便将缓冲区刷新到文件并保持更改。 调用close()后,不能使用文件描述符。

关闭文件: 处理文件时,必须使用函数fclose()将其关闭

关闭文件非常重要,尤其是对于输出文件。原因是输出通常是缓冲的。这意味着当你告诉C写一些东西时,例如

fprintf(ofp, "Whatever!\n");
它不需要立即写入磁盘,但可能会在内存中的缓冲区中结束。此输出缓冲区将暂时保存文本:

样本输出缓冲区:

----------------------------------------------
| a | b  | c | W | h | a | t | e | v | e | r |
----------------------------------------------
| ! | \n |   |   |   |   |   |   |   |   |   |
----------------------------------------------
|   |    |   |   |   |   |   |   |   |   |   |
----------------------------------------------
|   |    |   |   |   |   |   |   |   |   |   |
----------------------------------------------
...
(尽管有此图形,缓冲区实际上只是一维的。)

当缓冲区填满(或文件关闭)时,数据最终写入磁盘

参考

close()函数关闭程序与由句柄标识的打开文件之间的连接。任何未写入的系统缓冲区都会被刷新到磁盘,文件使用的系统资源也会被释放

粗体部分是关闭文件的主要原因

关闭文件会产生以下后果:

1) 文件描述符已解除分配
2) 进程在文件上拥有的任何记录锁都将被解锁
3) 当与管道或FIFO关联的所有文件描述符都已关闭时,将丢弃所有未读数据

  • 当你写入一个文件时,你首先要写入一个缓冲区 函数调用flush并将数据写入文件,但是 其他人只是写入缓冲区。当缓冲区已满时,它将刷新 在不直接调用刷新的情况下打开文件。你也可以 如果你想确定的话,随时冲洗
  • 关闭文件描述符后,您将无法再使用它

轻微修正。您的回答似乎表明文件应该仅使用
fclose
关闭。您也可以使用
close
关闭文件。只是
fclose
接受一个文件指针,
close
接受一个文件描述符。此外,许多实现在遇到换行符时会刷新缓冲区
\n
问题在于close(),而不是fclose()。对于close(),您在此处所写的内容实际上都不正确。帕万的说法可能更糟。。。带fclose的fopen对和带close的open(或creat)对;区别不仅仅在于文件指针和文件描述符之间,还在于完全不同的抽象/API之间(其中一个可能恰好通过另一个实现)。下面的一组答案说close()将缓冲区刷新到磁盘。但是,close()是一个POSIX函数,POSIX close()中没有这种情况。它只释放锁和释放资源。这里有几个答案声称缓冲区在close()时被刷新,但事实并非如此。。。POSIX close()不进行刷新,也与数据是否或何时写入设备无关。+1值得注意的是,这是这里唯一没有错误地断言close()刷新数据的答案。write()将数据从用户空间复制到系统缓冲区。系统缓冲区将在系统方便时或在同步()时刷新。close()与缓冲区的冲洗无关。它只释放文件锁和释放资源。
----------------------------------------------
| a | b  | c | W | h | a | t | e | v | e | r |
----------------------------------------------
| ! | \n |   |   |   |   |   |   |   |   |   |
----------------------------------------------
|   |    |   |   |   |   |   |   |   |   |   |
----------------------------------------------
|   |    |   |   |   |   |   |   |   |   |   |
----------------------------------------------
...