3

我有一个 node.js 程序,我在其中使用流将信息写入 SFTP 服务器。像这样的东西(简化版):

var conn = new SSHClient();
process.nextTick(function (){      
   conn.on('ready', function () {
      conn.sftp(function (error, sftp) {
         var writeStream = sftp.createWriteStream(filename);
         ...
         writeStream.write(line1);
         writeStream.write(line2);
         writeStream.write(line3);
         ...
      });
    }).connect(...);
});

注意我没有使用(可选)回调参数(在write() API 规范中描述),我不确定这是否会导致不良行为(即未按以下顺序写入的行:line1、line2、line3) . 换句话说,我不知道是否应该使用这种替代方案(更复杂的代码并且不确定效率是否更低):

writeStream.write(line1, ..., function() {
   writeStream.write(line2, ..., function() {
      writeStream.write(line3);
   });
});

(或使用async series()的等效替代方案)

根据经验,在我的测试中,我总是以所需的顺序写入文件(我的意思是,首先是 line1,然后是 line2,最后是 line3)。但是,如果这只是偶然发生,或者上面是使用 write() 的正确方法,我现在不知道。

我知道在流中写入通常是异步的(因为所有 I/O 工作都应该是)但我想知道 node.js 中的流是否保持内部缓冲区或类似的保持数据有序,所以每个 write() 调用都不会返回直到数据被放入这个缓冲区。

非常欢迎在实际程序中使用 write() 的示例。谢谢!

4

1 回答 1

4

write()(没有回调)是否保留 node.js 写入流中的顺序?

是的,它确实。它保留了您对该特定流的写入顺序。您正在写入的所有数据都通过将其序列化的流缓冲区。

但我想知道 node.js 中的流是否保留了一个内部缓冲区或类似的保持数据有序的缓冲区,因此每个 write() 调用在数据放入此缓冲区之前不会返回。

是的,所有数据都通过流缓冲区。.write()除非发生错误,否则在数据成功复制到缓冲区之前,操作不会返回。

请注意,如果您正在写入任何大量数据,您可能需要注意流上的流量控制(通常称为背压)。它可以备份并且可能会告诉您在写入更多内容之前您需要等待,但它确实会按照您发送它们的顺序缓冲您的写入。

如果.write()操作返回false,则流告诉您需要等待drain事件再写入。您可以在node.js 文档.write()这篇关于 backpressure的文章中阅读有关此问题的信息。

您的代码还需要侦听error事件以在写入流时检测任何错误。因为写入是异步的,它们可能会在稍后的某个时间发生,并且不一定反映在回调的返回值.write()err参数中。.write()您必须侦听该error事件以确保您在流中看到错误。

于 2018-04-16T20:23:57.573 回答