2010-03-16 100 views
3

有沒有辦法中止python寫入操作,使操作系統感覺不需要將未寫入的數據刷新到光盤?寫入後中止緩衝到磁盤?

我正在寫數據到USB設備,通常是很多兆字節。我在寫入時使用了4096個字節作爲我的塊大小,但看起來Linux很早就緩存了大量數據,並將其慢慢寫入USB設備。如果在寫入過程中的某個時候,我的用戶決定取消,我希望應用立即停止寫入。我可以看到從應用程序停止流動數據到USB活動指示燈停止閃爍之間存在延遲。幾秒鐘,通常高達約10秒。我發現應用程序保存在close()方法中,我假設,等待操作系統完成寫入緩衝數據。每次寫入後我都調用flush(),但這對延遲沒有任何影響。我已經搜索了python文檔的答案,但沒有發現任何東西。

+0

這完全取決於OS和文件系統。 「正確的」行爲(在正常情況下,異步掛載)是close()立即返回;它應該只等待刷新,如果你明確fdatasync()。你不可能找到一種便攜的方式來改變這種行爲,因爲它會在各個系統之間變化很大。 (從XP左右開始,Windows甚至不會在默認情況下將緩存寫入USB驅動器。) –

回答

2

它有點依賴於文件系統,但在某些文件系統中,如果您在分配文件之前(全部)刪除文件,寫入塊的IO將永遠不會發生。如果你截斷它,那麼這也可能是真實的,以便正在寫入的部分被截斷。

如果您仍想訪問數據,不確定是否可以放棄寫入。另外,支持這種文件系統的類型(例如xfs,ext4)通常不在USB記憶棒上使用。

如果要將數據刷新到光盤,請使用fdatasync()。只需將IO庫的緩衝區清理到操作系統中,就不會實現任何物理刷新。

+0

嗯......這很有趣,讓我嘗試一下... – Therealstubot

2

假設我理解這個正確的,你希望能夠'中止'和不刷新數據。這是可能的,使用ctype和一點點。這是非常依賴於操作系統的,所以我會給你的OSX版本,那麼你可以做將其更改爲Linux的東西:

f = open('flibble1.txt', 'w') 
f.write("hello world") 
import ctypes 
x = ctypes.cdll.LoadLibrary('/usr/lib/libc.dylib') 
x.close(f.fileno()) 
try: 
    del f 
catch IOError: 
    pass 

如果更改/usr/lib/libc.dylib到libc.so. 6在Linux的/ usr/lib中,那麼你應該很好。基本上通過調用close()而不是fclose(),不會調用fsync(),也不會刷新任何內容。

希望這很有用。

+0

Lee,這看起來應該可以工作,但是,我無法獲得理想的行爲。我調用了x.close(f.fileno()),它仍然在close()調用上執行flush和blocking操作,就像python close()命令一樣。 – Therealstubot

+0

如果發生這種情況,那麼.close()實際上並沒有被調用。您可以通過檢查返回碼來檢查。如果你得到無或數字,它不起作用 - 如果你得到0(零),那麼它確實。 – Lee

1

當您中止寫入操作時,在關閉它之前嘗試執行file.truncate(0);