使用Node.js处理大型流

时间:2017-05-01 22:32:01

标签: javascript node.js pdf-generation imagemagick-convert pdfkit

这是我尝试使用node和imagemagick转换工具将svg字符串转换为png缓冲区。然后使用png缓冲区使用pdfkit以pdf格式绘制图像。

Td; lr 我有一个很大的svg字符串需要进入“整个”子进程(即没有分块)。我该怎么做?

这是一个适用于小文件的示例。

var child_process = require('child_process');
var pdfDocument = require('pdfkit');


var convert = child_process.spawn("convert", ["svg:", "png:-"]),
svgsrc =  '<svg><rect height="100" width="100" style="fill:red;"/></svg>';

convert.stdout.on('data', function(data) {  
    console.log(data.toString('base64')
    doc = new pdfDocument()
    doc.image(data)
}


convert.stdin.write(svgsrc);
convert.stdin.end()

当svg字符串为'small'时(例如示例中提供的on),这是有效的 - 我不确定从小到大的截止位置。

但是,尝试使用更大的svg字符串(可能使用D3生成的内容),如[large string]。我碰到了:

  

错误:PNG文件不完整或损坏

所以我的问题是:在处理之前,如何确保convert子进程读取整个流?

有一些事情已知:

  • png缓冲区确实不完整。我用diff工具检查 应用程序生成的base64字符串 与在线的png-to-svg转换器的base64相比。没有损坏 string比损坏的字符串大得多。 (对不起,我没有 更具体的文件大小)。也就是说,转换工具似乎 在任何特定时间都不要阅读整个来源。

  • 源svg字符串未损坏(由事实证明 gist渲染它)

  • 在命令行中使用时,转换工具会正确生成一个 来自带有cat large_svg.svg | convert svg:png:-的svg“stream”的png文件因此不是转换工具的问题

这导致我找到了一个查看节点缓冲区大小以获得可写和可读流的兔子洞,但无济于事。也许有人在节点中使用了更大的流,可以帮助你开始工作。

1 个答案:

答案 0 :(得分:2)

正如@mscdex指出的那样,我必须等待这个过程才能完成 调整下游工作。所需要的只是等待end流上的convert.stdout事件,并在data事件上连接缓冲区。

// allocate a buffer of size 0
graph = Buffer.alloc(0)

// on data concat the incoming and the `graph`

convert.stdout.on('data', function(data) {

    graph = Buffer.concat([graph, data])
}
convert.stdout.on('end', function(signal) {

    // ... draw on pdf

}

修改

以上是我们使用@mscdex的更高效版本 建议在end回调上进行连接并保持chunksize参数以帮助缓冲区在连接块时分配大小。

// allocate a buffer of size 0
var graph = [];
var totalchunks = 0;

convert.stdout.on('data', function(data) {

    graph.push(data);
    totalsize +=data.length;
}
convert.stdout.on('end', function(signal) {

    var image = Buffer.concat(graph, totalsize);
    // ... draw on pdf


}