如何确保在完成写入文件之前不读取文件

Posted

技术标签:

【中文标题】如何确保在完成写入文件之前不读取文件【英文标题】:how to make sure not to read a file before finishing the write to it 【发布时间】:2010-07-16 18:07:01 【问题描述】:

我们知道,当尝试在 Linux 上使用 inotify 监视目录时,我们会在文件创建后立即收到通知(在其他进程完成写入之前)

有没有一种有效的方法来确保在其他进程完成写入文件之前不读取文件?

我们可能会添加延迟读取;但众所周知,它是有缺陷的。

为了更清楚地了解场景;这两个进程以不同的用户身份运行;预期的负载大约是每秒创建几百个文件。

【问题讨论】:

我想你不能只为每个文件创建一个命名信号量来确保一次只有一个进程在使用一个文件? Define "finish" ... 除非进程关闭文件,否则是否有可能确定进程是否“完成”写入,即使在原则上? 您是否可以控制读取/写入文件的程序,或者这也需要与“任何第三方程序”一起使用? 你的意思是基本的进程同步吗? 感谢大家的快速回复...创建文件到监控目录的过程是第三方软件,我无法控制。监视和读取文件的那个;是的,我对此有完全的控制权。 【参考方案1】:

根据您的问题,听起来您当前正在使用IN_CREATE(可能还有IN_OPEN)标志监视目录。为什么不同时使用IN_CLOSE 标志以便在文件关闭时收到通知?从那里,应该很容易跟踪文件是否已打开,并且您会知道您还不想尝试阅读它。

【讨论】:

谢谢jamessan;您的回复帮助我找到了一个似乎对我有用的解决方案。我现在监控 IN_CREATE 和 IN_CLOSE;将它们结合起来,将新来者挑选到我正在监视的目录中!感谢您的帮助。【参考方案2】:

在其他地方创建它,写入它,关闭它,然后重命名它 - 还是我遗漏了一些明显的东西?

【讨论】:

是的,这是正确的方法。或者以临时名称创建它并在完成后重命名。 只有我可以控制这个过程!这里我不!它是第三方作品。【参考方案3】:

您可以检查/proc/<pid>/fd 以查看文件是否仍处于打开状态。如果未在此处列出,则可以确定该进程不再使用它。

【讨论】:

有没有办法找到文件的fd,被一个外国进程打开了;我没有听说过。 AFAIK,fd 是特定于进程的,只有操作系统和进程才会知道 fd 和磁盘上的文件之间的关系;如果有办法,我很确定只有 root 才能使用。 @CodeMedic 查看目录。 fd 是文件本身的符号链接,因此您无需转换 fd -> name,您只需使用lstat 即可查看链接指向的文件。 例如:user@box:~# ls -l /proc/1433/fd/0 lr-x------ 1 root root 64 2010-07-16 15:31 /proc /1433/fd/0 -> /dev/null 只有当两个进程以同一用户身份运行时才有效。通常 /proc//fs/* 是用户可读的。最重要的是,我们将不得不每隔一秒左右遍历列表,从而遇到可伸缩性问题。还是谢谢 @CodeMedic 好吧,你没有指定,所以我建议你编辑你的问题并添加它。【参考方案4】:

也许 lsof 命令可以提供帮助。它列出了所有打开的文件。 $ man lsof

【讨论】:

这里的问题不是从 shell 复制。

以上是关于如何确保在完成写入文件之前不读取文件的主要内容,如果未能解决你的问题,请参考以下文章

如何从 servlet-filter 写入文件并在 Eclipse 中读取它?

PHP 中如何在同一个文件中写入而不覆盖以前写的内容

写入/读取文本文件 (C#)

如何在不重新打开文件的情况下读取然后写入/追加到文本文件?

Apache Beam 处理文件

如何确保文件在复制前完成?