2017-08-26 45 views
-1

我需要在執行fs.writeFile之前檢查文件是否存在,因此如果文件已經存在,fs.writeFile不能替換文件。使用fs.stat和fs.writeFile

使用fs.stat()來檢查文件是否存在調用fs.open()fs.readFile()fs.writeFile()之前不建議:但文檔下面說。相反,用戶代碼應直接打開/讀取/寫入文件,並處理文件不可用時引發的錯誤。

如果我直接調用fs.writeFile,該功能將替換該文件,如果它已經存在,而且error變量將是null

如果文件已經存在,我想忽略對fs.writeFile的調用。

謝謝。

回答

1

如果文件已經存在,我想忽略對fs.writeFile的調用。

使用wx標誌(證明here):

wx - 像'w'但如果路徑存在失敗。

fs.writeFile('/path/to/file', data, { flag : 'wx' }, function(err) { 
    if (err && err.code === 'EEXIST') { 
    console.log('file already exists, not overwriting'); 
    return; 
    } 
    ... 
}) 

編輯:我們不推薦fs.open/fs.writeFile/fs.readFile前使用fs.stat的原因是因爲固有的競爭條件:在調用之間fs.stat和(比如說)fs.writeFile,有時間的小窗口其中文件可能被創建,儘管在調用fs.stat時它還不存在。所以fs.writeFile仍然有可能覆蓋現有的文件。

如果您使用文件標誌,檢查存在是自動完成的。

1

羅伯特有正確答案(只是通過在適當的標誌fs.writeFile(fname, data, { flag : 'wx' }, ...)),但我想我會解釋爲什麼不建議使用fs.stat()隨後fs.writeFile()。當你做這樣的事情:

fs.stat(fname, function(err) { 
    if (err) { 
     // in the bit of time right here, there is a race condition 
     fs.writeFile(fname, data, function(err) { 
      // file written 
     }); 
    } 
}); 

有一個競爭條件。在任何類型的多進程系統或與其他系統共享的任何類型的文件系統中,可能存在fs.stat()報告該文件不存在的情況,但在該時刻和實際調用fs.writeFile()之間的某個其他進程或線程或計算機寫入該文件,現在您剛剛覆蓋了您不想執行的現有文件。所以,這在某些情況下根本不可靠,因此不推薦。

你需要的是一個原子操作,它將檢查它是否存在,如果不存在,它會爲你創建它。這將給你一個可靠的系統,使文件永遠不會被意外覆蓋。

通過傳遞wx標誌來fs.writeFile(),你告訴底層操作系統僅在文件不存在寫這些字節的文件,它會以原子方式不具備做多線程/過程/計算機競賽條件。


是有限制的競爭條件和有你的系統實際上不會受到它(只都不能寫入該文件的一個Node.js的過程)的情況下,但它只是更安全只是總是以安全的方式進行編碼,無論如何,實際上,安全的方式就是代碼少。

+0

我想我們都有這種感覺,值得更多的解釋:D – robertklep

+0

@robertklep - 是的,在評論中提到的OP,他們不明白原因和你的答案(我upvoted)沒有包含解釋在我寫了這個。 – jfriend00

+0

是的,我也意識到,指出_why_這不是推薦:)是一件好事:) – robertklep