2013-06-11 17 views
5

我有一個Node.js應用程序,它將一些配置數據存儲在一個文件中。如果更改了某些設置,配置文件將寫入磁盤。在Node.js中事務性地寫文件

目前,我正在使用一個簡單的fs.writeFile

現在我的問題是:當文件被寫入時Node.js崩潰會發生什麼?是否有機會在磁盤上存在損壞的文件?或者Node.js保證文件是以原子方式編寫的,以便舊版本或新版本有效?

如果不是,我怎麼能實現這樣的保證?有沒有這個模塊?

回答

7

當文件寫入時Node.js崩潰時會發生什麼? 是否有機會在磁盤上存在損壞的文件?或者Node.js 保證文件是以原子方式寫入的,以便舊版本或新版本的 有效?

節點只通過系統調用實現一個(薄)異步包裝,因此它不提供有關寫入原子性的任何保證。實際上,fs.writeAll反覆調用fs.write,直到寫入所有數據。你說得對,當Node.js崩潰時,你最終可能會損壞文件。

如果不是,我怎麼能實現這樣的保證?有沒有這個模塊?

我能想出的最簡單的解決方案是使用用於FTP上傳:

  1. 將內容保存到具有不同名稱的臨時文件。
  2. 將內容寫入磁盤時,將臨時文件重命名爲目標文件。

man page說,重命名保證離開NEWPATH的實例到位(像Linux或OSX Unix系統)。

+0

我可以確認,在OSX中這並不能完全解決問題,但它確實減少了文件損壞的發生率 –

6

fs.writeFile,就像fs模塊中的所有其他方法都是圍繞標準POSIX函數(如docs中所述)的簡單包裝一樣實現。

掘的NodeJS'代碼一點,人們可以看到,在fs.js,所有的包裝的定義,使用fs.c其所有文件系統調用。更具體地說,write方法用於寫入緩衝區的內容。事實證明,在POSIX specification寫明確地說:

原子/非原子:寫是原子的,如果寫在 一次操作總量爲不與任何其他方法對數據進行交織。 當有多個寫入器將數據發送到 單個閱讀器時,這非常有用。應用程序需要知道有多大的寫請求可以預期以原子方式執行。這個最大值被稱爲 {PIPE_BUF}。本卷的IEEE Std 1003。1-2001沒有說明多於{PIPE_BUF}字節的 寫入請求是否是原子性的,但要求 寫入{PIPE_BUF}或更少的字節應爲原子。

因此,只要緩衝區的大小小於PIPE_BUF,它似乎寫得很安全。這是一個與系統相關的常量,所以你可能需要在別的地方檢查它。

+0

根據http://manpages.courier-mta.org/htmlman7/pipe.7.html,PIPE_BUF至少需要512字節,在Linux中是4.096字節。感謝您指出這一點,因爲這是非常好的和有趣的東西要知道:-) –