我正在Windows 8上運行node v4.2.0。我發現fs.mkdirSync()偶爾拋出EPERM沒有明顯的原因。爲什麼節點mkdirSync()拋出異常?
我設法用這個測試代碼重新創建它,我保存在一個文件bug.js.
var fs = require("fs");
var i;
for (i = 0; i < 100000; i += 1) {
fs.mkdirSync("xx");
fs.rmdirSync("xx");
}
這是跟蹤我偶爾得到:
C:\WIP>node bug
C:\WIP\bug.js:0
Error: EPERM: operation not permitted, mkdir 'C:\WIP\xx'
at Error (native)
at Object.fs.mkdirSync (fs.js:799:18)
at Object.<anonymous> (C:\WIP\bug.js:4:8)
at Module._compile (module.js:435:26)
at Object.Module._extensions..js (module.js:442:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:311:12)
at Function.Module.runMain (module.js:467:10)
at startup (node.js:134:18)
at node.js:961:3
它並不總是發生,即使有10萬循環。事實上,它是一個滑溜的野獸 - 如果我多次運行bug.js,似乎會降低觸發異常的可能性。當我嘗試捕捉異常時,發現它在成千上萬的循環成功迭代之後發生。
爲什麼會發生異常?有什麼辦法可以避免異常嗎?
我沒有設法在Linux上重新創建它,所以是的感覺就像是Windows的東西。我不同意你應該在mkdirSync()周圍使用try {} catch {}。有時候你的程序需要創建一個文件夾,並且有權利期望它能夠正常工作,如果沒有,它就無處可去。爲什麼它不工作?我只是做了rmdirSync() - 最後一個操作應該完成並且不會發生重疊。 – James
我的猜測是,在windows的文件系統管理中存在一些問題 - 也許mkdir在後臺寫入磁盤時報告了「完成」,然後rm被觸發到一個尚未創建的句柄/ is被創建,因此你得到EPERM異常。但你說得對 - 看代碼這是一個錯誤。代碼是有效的,在這種情況下不應該拋出像這樣的異常。是的,如果它不能發揮作用沒有抓住它應該做的,但通常它的任務不應該停止你的整個計劃。行尾 - 我同意,這是越野車。 –
@James:爲了提高速度,所有現代操作系統都將異步磁盤驅動程序實現爲異步。所以寫操作可能會重疊(實際上,在Windows中,這個API稱爲重疊I/O)。看起來,Linux具有更強大的異步I/O實現(部分原因是幾年前Torvalds先生本人突然對優化Linux磁盤I/O感興趣)。 – slebetman