asynchronous文件追加

在试图学习node.js / socket.io我一直在搞创build一个简单的file upload,从客户端浏览器的数据块,并在服务器端重新组装。

用于接收块的socket.io事件如下所示:

socket.on('sendChunk', function (data) { fs.appendFile(path + fileName, data.data, function (err) { if (err) throw err; console.log(data.sequence + ' - The data was appended to file ' + fileName); }); }); 

问题是由于asynchronous调用,数据块不一定以接收到的顺序附加。 典型的控制台输出如下所示:

  • 1 – 数据被附加到文件testfile.txt
  • 3 – 数据被附加到文件testfile.txt
  • 4 – 数据被附加到文件testfile.txt
  • 2 – 数据被附加到文件testfile.txt

我的问题是,以非阻塞的方式实现这个function的正确方法是什么,但强制执行顺序。 我已经看过像async这样的库,但是真的希望能够处理每个进程,而不是创build一个系列,并在所有文件块都运行后运行。我仍然试图围绕所有这个事件驱动stream,所以任何指针都很棒。

通常你会使用一个队列来等待被写入的数据,然后每当前一个append完成时,就尝试写下一个片段。 像这样的东西:

 var parts = []; var inProgress = false; function appendPart(data){ parts.push(data); writeNextPart(); } function writeNextPart(){ if (inProgress || parts.length === 0) return; var data = parts.shift(); inProgress = true; fs.appendFile(path + fileName, data.data, function (err) { inProgress = false; if (err) throw err; console.log(data.sequence + ' - The data was appended to file ' + fileName); writeNextPart(); }); } socket.on('sendChunk', function (data) { appendPart(data); }); 

您将需要展开以保持parts队列,并基于fileName进行inProgress 。 我的例子假设这些将是简单的恒定。

既然你需要添加顺序或同步。 你可以使用fs.appendFileSync而不是fs.appendFile 。 这是处理它的最快方法,但是会损害性能。

如果你想自己asynchronous处理它,使用EventEmitter来处理这个问题。 事实certificate,响应(以及请求)对象是stream。 使用fs.createWriteStream创build一个可写入的stream,并写入所有片段以追加文件。

 fs.createWriteStream(path, [options])# Returns a new WriteStream object (See Writable Stream). options is an object with the following defaults: { flags: 'w', encoding: null, mode: 0666 } 

在你的情况下,你会使用标志:'a'