node.js读取文件困境

下面的一段代码创build一个文本文件,然后读取它,覆盖它,并再次读取它。 除了文件的创build之外,三个I / O操作使用Node.js async readFile和writeFile来执行。

我不明白为什么第一次阅读没有返回错误,没有数据 。 这个代码的输出是:

  • 开始…
  • 完成。
  • 先读取EMPTY数据返回!
  • 写完就OK
  • 第二次读取返回的数据:更新文本

即使这些操作是以任意顺序发生的(由于它们的asynchronous性质),我也不希望得到一个“空数据”对象。

任何想法,为什么我在阅读文件时得到一个空的数据(并没有错误)?

有什么我可以做,以确保文件内容被读取?

var fs = require('fs'); var fileName = __dirname + '/test.txt'; // Create the test file (this is sync on purpose) fs.writeFileSync(fileName, 'initial test text', 'utf8'); console.log("Starting..."); // Read async fs.readFile(fileName, 'utf8', function(err, data) { var msg = ""; if(err) console.log("first read returned error: ", err); else { if (data === null) console.log("first read returned NULL data!"); else if (data === "") console.log("first read returned EMPTY data!"); else console.log("first read returned data: ", data); } }); // Write async fs.writeFile(fileName, 'updated text', 'utf8', function(err) { var msg = ""; if(err) console.log("write finished with error: ", err); else console.log("write finished OK"); }); // Read async fs.readFile(fileName, 'utf8', function(err, data) { var msg = ""; if(err) console.log("second read returned error: ", err); else if (data === null) console.log("second read returned NULL data!"); else if (data === "") console.log("second read returned EMPTY data!"); else console.log("second read returned data: ", data); }); console.log("Done."); 

你的代码是要求比赛条件。 您的第一次同步写入可能正在写入文件,但是同时将第一次读取,第二次写入和第二次读取放入事件循环。

这里会发生什么? 第一次读取从文件系统获得读取权限,第二次写入从文件系统获得写入许可,并立即将文件归零以供将来更新,然后第一次读取读取现在为空的文件。 然后第二次写入开始写入数据,第二次读取没有获得读取权限,直到完成。

如果你想避免这种情况,你需要使用stream程:

 fs.writeFileSync(filename, 'initial', 'utf8'); fs.readFile(filename, 'utf8', function(err, data) { console.log(data); fs.writeFile(filename, 'text', 'utf8', function(err) { fs.readFile(filename, 'utf8', function(err, data) { console.log(data); }); }); }); 

如果这个“金字塔”侮辱你的编程的敏感性(为什么不呢?)使用asynchronous库的series函数:

 fs.writeFileSync(filename, 'initial', 'utf8'); async.series([ function(callback) { fs.readFile(filename, 'utf8', callback); }, function(callback) { fs.writeFile(filename, 'text', 'utf8', callback); }, function(callback) { fs.readFile(filename, 'utf8', callback); } ], function(err, results) { if(err) console.log(err); console.log(results); // Should be: ['initial', null, 'text'] }); 

编辑:更紧凑,但也更“神奇”的不熟悉async库和现代Javascriptfunction的人:

 fs.writeFileSync(filename, 'initial', 'utf8'); async.series([ fs.readFile.bind(this, filename, 'utf8'), fs.writeFile.bind(this, filename, 'text', 'utf8'), fs.readFile.bind(this, filename, 'utf8'), ], function(err, results) { if(err) console.log(err); console.log(results); // Should be: ['initial', null, 'text'] }); 

EDIT2:为我做正确的编辑,而不必查找bind的定义。 第一个参数需要是this对象(或者你想用的任何东西)。