2011-09-29 120 views
6

我有一个Python脚本,用于检查拾取目录并处理它找到的任何文件,然后删除它们。拾取目录:如何拾取仍在写入的文件?

如何确保不会拾取正在将该文件放入该目录的进程正在写入的文件?

我的测试案例非常简单。我将300MB文件复制粘贴到拾取目录中,并且脚本通常会抓取仍在写入的文件。它仅对部分文件进行操作,然后将其删除。这会引起操作系统中的文件操作错误,因为它正在写入的文件消失。

  • 我试图在打开/处理/删除它之前获取文件上的锁(使用FileLock模块)。但是这并没有帮助。

  • 我已经考虑检查文件的修改时间,以避免X秒内的任何事情。但那似乎很笨重。

我的测试是在OSX上,但我试图找到一个解决方案,将跨主要平台的工作。

我在这里看到一个类似的问题(How to check if a file is still being written?),但没有明确的解决方案。

谢谢

+1

正在编写该文件的应用程序应该真的是自动完成的,但我意识到您可能无法控制这个。 –

+0

我认为要可靠地做到这一点,要么文件需要原子化写入,要么需要通过操作系统直接或间接与写入进程进行通信。有特定于操作系统的解决方案,如文件锁定和修改事件,但AFAIK没有任何跨平台的。检查修改时间可能与您将获得跨平台解决方案一样好。 –

回答

2

作为解决方法,您可以听文件修改的事件(watchdog是跨平台的)。修改的事件(至少在OS X上)每次写入都不会被触发,只会在关闭时触发。因此,当您检测到修改的事件时,您可以假定所有写入都已完成。

当然,如果文件正在分块写入,并且在每个分块后保存,这将不起作用。

1

一个解决这个问题将是改变程序写入文件到文件写入到一个临时文件,然后再当它完成移动该临时文件到目的地。在大多数操作系统上,当源和目标位于同一文件系统上时,移动是原子性的。

+0

我非常想做到这一点,但不幸的是,我无法控制系统的这一部分:( – Jagu

1

如果你无法控制书写部分,你所能做的就是自己看文件,当它停止增长一段时间时,称它为好。我必须自己使用这种方法,并发现40秒对我的状况是安全的。

0

您是否曾尝试在应对之前打开该文件?如果该文件仍在使用中,则open()应该抛出异常。

try: 
    with open(filename, "rb") as fp: 
    pass 
    # Copy the file 
except IOError: 
    # Dont copy 
+0

这不适用于所有的操作系​​统。Linux和OSX不需要文件被锁定时在Windows上,你可能想获得一个写锁而不是读锁,以确保没有其他进程正在写入文件(使用'wb'而不是'rb')。 –

1

由于文件锁定机制不可移植,每个操作系统都会有不同的解决方案。

  • 在Windows上,您可以使用操作系统锁定。
  • 在Linux上,您可以查看打开的文件(类似lsof如何),如果文件处于打开状态,请将其保留。