node.js 中与 fs.createWriteStream 关​​联的事件

Posted

技术标签:

【中文标题】node.js 中与 fs.createWriteStream 关​​联的事件【英文标题】:event associated with fs.createWriteStream in node.js 【发布时间】:2012-10-20 19:27:27 【问题描述】:

在写入流时到达 EOF 时会触发什么事件? 我的代码如下。它是根据http://docs.nodejitsu.com/articles/advanced/streams/how-to-use-fs-create-write-stream

但令人惊讶的是,我的“结束”事件从未被触发。当我检查http://nodejs.org/api/stream.html#stream_event_end 时,我看到可写流在“结束”时没有任何事件


var x = a1.jpg;
var options1 = 'url': url_of_an_image, 'encoding': null;
var r = request(options1).pipe(fs.createWriteStream('/tmp/imageresize/'+x));

r.on('end', function()
    console.log('file downloaded to ', '/tmp/imageresize/'+x);

如何捕获 EOF 事件?

【问题讨论】:

【参考方案1】:

2013 年 10 月 30 日更新

可读 Steam emit close event when the underlying resource done writing.

r.on('close', function()
  console.log('request finished downloading file');
);

但是如果你想捕捉fs完成数据写入磁盘的那一刻,你需要Writeable Stream finish event:

var w = fs.createWriteStream('/tmp/imageresize/'+x);

request(options1).pipe(w);

w.on('finish', function()
  console.log('file downloaded to ', '/tmp/imageresize/'+x);
);

【讨论】:

关闭事件是否意味着所有内容都已刷新到磁盘,或者它仍然在操作系统写入缓冲区中?什么时候可以安全地退出该过程? 我会在调用请求之前绑定事件以完成。这是一个竞争条件,只是碰巧解决了对你有利的问题,不是吗? @LeoRomanovsky 不,这不是竞争条件,因为我正在同步注册我的事件处理程序。 node.js 中的流是异步的,因此在 node.js 事件循环的下一个滴答之前不会触发任何事件。 @LeonidBeschastny 关闭事件与可读流的结束事件有何不同? 'end' 事件在 Readable Stream 耗尽时发出,即当没有更多数据可以从中消耗时。 'close' 事件在底层资源关闭时发出,即当没有更多数据要写入其中时。 It's all in the docs,顺便说一句。【参考方案2】:

这确实很旧,但这仍然为我节省了很多时间。

    leonid-beschastny 的解决方案是正确的。但是,调用的完整顺序有一个非常细微的差别。解决方案都来自专家,像我这样的新手迷路了 - 由于简单的差异,例如 - 如何创建流或描述中遗漏的对象。

    此外,这是许多其他场景的通用解决方案。当您通过管道传输到 writableStream 时 - 并且到包含此操作的异步函数时 - 返回。流式传输尚未完成 - 因此正在传输到的可能的图像/文档/pdf 尚未创建。它将大小为 0 KB。

    通过简单的步骤在这里分享。

    a. createPdfKitDocument with your definition as required.
    
    b. Create the writeStream the way you want as per your design.
    
    c. Pipe your prepared document to this stream.
    
    d. Add this finish event to your writeStream.
    
    e. Most important - without this it doesn't work.
    

这里

var pdfStream = printer.createPdfKitDocument(docDefinition); //a
let writerStream = fs.createWriteStream(fullfileName); //b
pdfStream.pipe(writerStream); //c
writerStream.on('finish', function () 
    //This could be your callback function.
    callback());
) //d
pdfStream.end(); //e

    我还提到了这些链接 - 它们可能对某人有所帮助 一种。 PDF download fails using PDFMake in NodeJS这给了我发帖的线索。

    主要问题是 - createWriteStream 没有完成 [由于任何原因] - 到包含它的异步函数返回时。

    leonid-beschastny 也正确地说不会发生竞争条件 - 我通过交换 pdfStream.pipe(writerStream); 的位置来测试我的代码

writerStream.on('finish', function () 
    //This could be your callback function.
    callback());
)

希望它能帮助更多的人。

【讨论】:

对我来说最重要的是“完成”事件。感谢您的解释并节省了我的时间。

以上是关于node.js 中与 fs.createWriteStream 关​​联的事件的主要内容,如果未能解决你的问题,请参考以下文章

node.js 中与 fs.createWriteStream 关​​联的事件

在 node.js 中与 socket.io 私聊

使用 Node.js 和 MongoDB 存储密码

如何将流 responseType 传递给我的客户端?

Node.js 模块以及npm包的管理和使用

Node.js 模块以及npm包的管理和使用