2011-09-29 123 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如何),如果文件處於打開狀態,請將其保留。