当您读取文件而被覆盖时会发生什么?


Answers:


19

这取决于作者的所作所为。

如果写入者覆盖现有文件,那么当写入者超越读取者(如果有)时,读取者将看到新内容。如果作者和阅读者以可变的速度前进,则阅读者可能会看到新旧内容。

如果写入者在开始写入之前将其截断,则读取器将在该点的文件末尾运行。

如果作者创建了一个新文件,然后将新文件移动到旧名称,则读者将继续从旧文件中读取。如果移动或删除了打开的文件,则打开文件的进程将继续从同一文件读取。如果文件被删除,则实际上它仍保留在磁盘上(但是无法再次打开它),直到最后一个进程将其关闭为止。

Unix系统往往没有强制性的。如果应用程序要确保其编写器组件和读取器组件不会踩到彼此的脚趾,则由开发人员决定使用适当的锁定。在某些例外情况下,可以保护内核打开的文件不被用户应用程序写入,例如,循环安装的文件系统映像或在某些unix变体上执行的可执行文件。


Gilles,您的解释是否也适用于ftp/ sftp场景?假设某个进程开始读取已传输的ftp文件,而同一文件的另一个版本由于新的传输而将其覆盖。
iruvar

@ 1_CR是。在这种情况下,写入者和读取者是ftpd进程。
吉尔斯(Gillles)“所以-不要再邪恶了”

在这里超车是什么意思?
Victor Choy

@VictorChoy Standard的含义:在别人之后/之后开始,并在某个时候向前走。
吉尔(Gilles)'所以

18

这是典型的比赛条件,因此根据定义,结果是无法预测的。

除其他外,这取决于

  • fopen(3)open(2)写入模式
  • 编写者如何/是否正在缓冲其输出,
  • 读者如何阅读文件,
  • 读者和作家之间的速度差异,
  • 读写开始之间的时间差。
  • 当然,在现代多核计算机上,由于其他因素(例如流程调度)的影响,事情变得更加复杂。

如果您需要能够在重写文件时读取文件,则可以使编写者制作文件的临时副本,对其进行修改,然后将其复制回原始文件。例如,这种方式就是这样rsync做的。有多种方法可以实现此目的,但没有免费的午餐。每种方法都有其自身的缺点和影响。


1
这个答案比我的要全面得多。删除我的答案。
杀手主义者2012年

0

以前的响应者对此有更全面的解释,但这绝对是一个有效的技巧,几乎可以完全按照他的意愿去做:

$ tail -f <filename>

在写入文件时将向您显示文件的结尾。例如,如果您想将STDERR通过管道传输到文件,但仍在另一个终端窗口中看到它,则非常方便。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.