我有一个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 specification中描述),我不确定这是否会导致不良行为(即行不按以下顺序写入:line1,line2,line3)。换句话说,我不知道是否应该使用这种替代方案(更复杂的代码并且不确定效率是否更低):
writeStream.write(line1, ..., function() {
writeStream.write(line2, ..., function() {
writeStream.write(line3);
});
});
(或使用async series())
的等效替代方案根据经验,在我的测试中,我总是以所需的顺序写入文件(我的意思是,iirst line1,然后是line2,最后是line3)。但是,如果这只是偶然发生,或者以上是使用write()的正确方法,我现在不会。
我理解在流中写入通常是异步的(因为所有的I / O工作都应该是)但是我想知道node.js中的流是否保留了一个内部缓冲区或类似的数据来保持数据的顺序,所以每个write()调用都不会#39; t返回,直到数据被放入此缓冲区。
非常欢迎在真实程序中使用write()的例子。谢谢!
答案 0 :(得分:3)
write()(没有回调)是否在node.js写入流中保留顺序?
是的。它保留了对特定流的写入顺序。您正在编写的所有数据都通过流缓冲区进行序列化。
但是我想知道node.js中的流是否保留了一个内部缓冲区或者类似的数据来保持数据的顺序,所以每次write()调用都不会返回,直到数据被放入这个缓冲区。
是的,所有数据都通过流缓冲区。除非发生错误,否则在数据成功复制到缓冲区之前,.write()
操作不会返回。
请注意,如果您正在编写任何大量数据,则可能需要注意流上的流量控制(通常称为背压)。它可以备份并且可能告诉您在写更多内容之前需要等待,但它会按照您发送的顺序缓冲您的写入。
如果.write()
操作返回false
,则流会告诉您在编写之前需要等待drain
事件。您可以在node.js docs for .write()
和this article about backpressure中了解此问题。
您的代码还需要侦听error
事件,以便在写入流时检测到任何错误。由于写入是异步的,因此它们可能在稍后的某个时间发生,并且不一定反映在从.write()
或err
参数到.write()
回调的返回值中。您必须侦听error
事件,以确保在流上看到错误。