NodeJS流响应以防止内存不足错误

时间:2014-04-06 14:17:35

标签: node.js memory-management stream zlib

我有以下代码:

 response.writeHead(200 , {
   'Content-Type': 'application/vnd.ms-excel',
   'Content-encoding': 'gzip',
   "Content-Disposition": "attachment; filename="+getFileName()
});

var zlib = require("zlib");
var data = getData(); //some arbitrary data from a method
var outputStr = "";
var header = "some header";
var footer = "some footer";

outputStr+= header;

for(i=0;i<data.length;i++) {
  outputStr+= data[i].utils.generateString(); //xml parser and various whatnots resulting in a string
}

outputStr+= footer;

zlib.gzip(outputStr, function(err, result) {
  response.end(result); //works on small strings
})

有时,我的字符串长度超过512mb的限制(这很好),因此,在32位系统上,所以我得到:

FATAL ERROR: CALL_AND_RETRY_0 Allocation failed - process out of memory

我一直在阅读有关流的内容,但是所有示例都是在阅读文件,而不是生成值。

如何在迭代(我的循环)中创建流并将数据推入其中,而不是将其全部写入字符串并将其作为响应推送。

输出将调用文件下载非常重要,与今天一样,以及gzip支持(这是异步的,因此需要考虑)

2 个答案:

答案 0 :(得分:0)

您想要创建流式响应,因此您可以在便捷功能之外创建Gzip流。

示例:

var zlib=require('zlib');
var fs=require('fs');

var gz=zlib.createGzip();
var res=fs.createWriteStream('./test.gz');

gz.pipe(res);

var data=['hi','test','data'];
var i;
for (i=0;i<data.length;i++) {
    gz.write(data[i]);
}
gz.end();  // this will implicitly call 'res.end()' by default

答案 1 :(得分:0)

如果此数据代码生成离散字符串,您应该能够在循环中使用response.write来实现此目的。

for(i=0;i<data.length;i++) {
  response.write(data[i].utils.generateString());
}