2011-06-15 151 views
2

我有一個在Debian上運行的Python程序,它使用File對象輸出數據。我想對我的文件的大小設置限制,但我不想停止寫入文件 - 我只想刪除最早的行(位於文件的頂部)。我的數據是隨着數據包從客戶端到達而隨機寫入的(想想web日誌記錄)。限制Python輸出文件大小

我知道它的工作原理,但是如果我的文件超出限制,通過使用File.tell()的組合,然後執行下面的系統命令,將它關閉是我最大的興趣?

sed -i '1 d' filename 

一旦達到大小限制,它會每次執行sed。有沒有更好的辦法?

回答

2

原因Python的日誌記錄模塊不使用這種策略,因爲它需要的性能損失。如果根據大小或年齡旋轉的日誌文件根本不可接受,那麼就像我看到的那樣,您有兩個基本選擇:覆蓋日誌文件,寫入臨時文件然後替換。

如果覆蓋日誌文件,您應該首先選擇文件中的整數地址(第一個\ n字節的位置加上一個可能),它將成爲'新的零'(稱爲X)。然後選擇一個塊大小,也許32K。然後開始計數。尋找到X +塊大小*塊號,讀取一個塊。尋求塊大小*塊號,寫回塊。讀取時到達EOF時,將文件截斷爲長度塊大小*塊編號。

如果使用臨時文件,請找到'新零',將文件的其餘部分複製到臨時文件,然後將其重命名爲原始名稱。比我想的更容易,無論如何更容易解釋,但使用更多的空間。

以下所有內容,請寫入新數據並關閉文件。每個日誌消息都必須執行整個過程。祝你好運!

3

有一個原因,沒有日誌記錄系統使用這種策略。您不能在不重寫整個文件的情況下從文件中刪除第一行,因此它在大文件上非常緩慢。另外,當你重寫文件時,你無法將新數據寫入文件。

正常的策略是在當前文件變得太大時開始寫入新文件。然後,您可以刪除超過閾值的文件。這是其他人提到的「日誌輪換」。

如果你真的想創建一個隊列,在添加一個新數據的時候刪除一行數據,我建議使用數據庫。 MongoDB和其他數據庫管理器支持數組,但是如果需要,你可以用SQL數據庫做類似的事情。

0

除非您需要近實時訪問來自另一個進程的文件,否則我可能會將每個日誌行寫入固定大小的collections.deque。您可以實現一種方法,將collections.deque中的項目(行)同步到日誌文件中的行。