2011-04-22 60 views
10

如何检查文件是否仍在写入?我需要等待一个文件被创建,写入并被另一个进程关闭,所以我可以继续在我的进程中再次打开它。如何检查文件是否仍在写入?

+1

你能解释一下你的用例吗?也许使用管道(简单管道或命名管道)而不是单个文件对你来说更容易。 – evnu 2011-04-22 18:36:06

+0

如果有帮助,尽管... write/writev是原子的。因此,只要您要保证的是您的写入不会与其他写入混在一起,那么您所要做的就是确保您写入的所有内容都适合写入writev()的单个调用。然后,文件是否打开并不重要,操作系统会以某种方式对其进行排序。 – Damon 2011-04-22 22:36:08

+0

可能的重复[如何确保在写入之前不读取文件](http://stackoverflow.com/questions/3267685/how-to-make-sure-not-to-read-a-文件之前完成写入它) – Beginner 2015-02-17 17:04:28

回答

5

一般来说,这是一个难以解决的问题。在某些情况下,您可以询问文件是否为开放;但是,如果其他进程是脚本,则可能会多次打开并关闭该文件。我强烈建议您使用咨询锁或其他明确的方法让其他进程在完成文件时进行通信。

这就是说,如果这不是一个选项,那么还有另一种方法。如果您查看/proc/<pid>/fd目录,其中<pid>是某个正在运行的进程的数字进程ID,那么您会看到一些符合连接的进程打开的文件。符号链接上的权限反映文件打开的模式 - 写入权限意味着它被打开为写入模式。

因此,如果您想知道某个文件是否处于打开状态,只需扫描每个进程的/proc条目以及其中的每个文件描述符,即可查找到文件的可写符号链接。如果你知道另一个进程的PID,你也可以直接看看它的proc入口。

这当然有一些主要缺点。首先,除非你是root用户,否则你只能看到自己进程的打开文件。它也相对较慢,只适用于Linux。再次,如果其他进程打开和关闭文件多次,您就会陷入困境 - 您可能最终在关闭期间看到它,并且没有简单的方法知道它是否会再次打开它。

+3

如果某个远程进程通过NFS写入文件,您将不会看到它。 (除非有实际写作的本地进程,但我认为它是在内核中完成的。) – 2011-08-15 22:39:32

3

写完读写过程感兴趣的数据文件后,您可以让写入过程写一个哨兵文件(比如说“sentinel.ok”)。在读过程中,您可以检查哨兵的存在在读取数据文件之前,确保数据文件完全写入。

1

@ blu3bird使用哨兵文件的想法并不差,但它需要修改写入文件的程序。

这里还有一个可能性,还需要修改的作家,但它可能是更稳健:

写入到一个临时文件,说“foo.dat.part”。当写入完成时,将“foo.dat.part”重命名为“foo.dat”。这样,读者根本不会看到“foo.dat”,或者会看到它的完整版本。

0

您可以尝试使用inotify

http://en.wikipedia.org/wiki/Inotify

如果知道该文件将被打开一次,写,然后关闭,将有可能为您的应用程序等待IN_CLOSE_WRITE事件。

但是,如果其他应用程序执行文件写入的行为更像打开,写入,关闭,打开,写入,关闭....那么您需要一些其他机制来确定何时其他应用程序已经真正完成了文件。