2009-08-24 70 views
1

原子地創建一個新文件的'最佳實踐'(就像我看到的那樣)是打開一個臨時文件(使用tmpfile()),然後將文件移動到最終位置。原子創建文件的最佳方式

但是,如果臨時文件位於不同的掛載點上,這將無法正常工作,因爲這會導致文件逐漸累積並導致不必要的IO開銷。

另一種選擇是在與最終目的地相同的目錄中創建一個臨時文件,但這有一個缺點,即爲用戶創建一個不尋常的文件(像MS Word和ViM這樣的應用程序可以這樣做,但我也考慮過不良行爲)。

是否有類似tmpfile()的方法可以指定掛載點?我意識到這可能不存在內置的PHP,所以Posix/C函數或shell調用也是可以接受的。

回答

1

maildirmaildir協議開發qmail爲多個作家提供安全的文件創建到同一個目標目錄,甚至跨NFS。在這個方案中,「tempfile」目錄保證與目標目錄在同一個文件系統上。

safecat通過六個步驟將數據寫入應用maildir的算法:

算法以高效殼工具,safecat,其手冊頁呈現算法被方便地實現。 首先,stat()是兩個目錄tempdir和destdir,並且除非兩個目錄都存在且可寫,否則退出 。其次,它的stat()是 ,名稱爲tempdir/time.pid.host,其中time是自1970年GMT開始的 以來的秒數,pid是程序的進程ID,主機名是 。第三,如果stat()返回了ENOENT以外的任何其他值,則程序將休眠兩秒鐘,更新時間,並再次嘗試stat() ,有限次數。第四,該程序創建 tempdir/time.pid.host。第五,程序NFS將消息寫入 文件。第六,程序鏈接()將文件保存到destdir/time.pid.host。在 即時數據已成功寫入。

此外,safecat會在創建 tempdir/time.pid.host之前啓動24小時定時器,並在定時器到期時終止寫入。當 錯誤,超時或正常完成時,safecat嘗試取消鏈接() tempdir/time.pid.host。

0

正如你在談論「安裝點」時,我假設你處於類Unix環境。

也許你可以認爲它是一種解決方法或不良行爲,但我認爲在同一個目標文件夾上創建一個隱藏的(.tmpfile)臨時文件是可以接受的。

當然,您可以在適用於此任務的應用程序無法訪問的同一個掛載點上創建特定的文件夾,如果您不想看到任何虛假文件,可以在同一掛載點上模擬tempfile()在目的地目錄中。

+0

Windows有掛載點,至少在NTFS上。 – Thorarin 2009-08-24 16:40:23

+0

這實際上正是我的第二選擇,我最好避免這樣做。 – Evert 2009-08-24 16:56:51

+0

@Thorarin,你可以給我更多關於這方面的信息。謝謝。 – drAlberT 2009-08-24 17:22:05

2

不,POSIX堆棧中沒有這樣的方法。 tmpfile()和tmpname()用於常規臨時目錄。有tempnam(),您可以在其中指定臨時文件的目標目錄。但基本上是實現你描述的第二種選擇的一種方式。

+0

我很好奇,如果可能有某種方式可以打開一個INode,並且只在路上提供一個文件名。我知道可以打開文件,取消鏈接文件,然後繼續寫作。 – Evert 2009-08-24 16:57:49

+0

我不認爲這是可能的,但它確實很好。如果我記得,我會看看VFS源代碼。 – dmeister 2009-08-24 20:25:22

-1

我不得不這樣做,並與MySQL數據庫。只需將表格中需要的信息存儲在表格中,當我完成時,我只刪除了該記錄。只是一個想法:)

+0

但是,這可能會導致類似數量的I/O開銷。通常,數據庫甚至不在同一臺服務器上。 – Thorarin 2009-08-24 16:43:22

+0

使用MySQL絕對是糟糕的 – Evert 2009-08-24 16:58:33

相關問題