我有相当大的(30 by gzip,大约300 by)gzip的rdf文件,我需要逐行处理这个文件,并将其压缩回另一个文件。所以这就是我目前所拥有的(测试中的file是大约150MB的gzipped)
const fs = require('fs');
const zlib = require('zlib');
const readline = require('readline');
const readStream = fs.createReadStream('21million.rdf.gz').pipe(zlib.createGunzip());
const writeStream = fs.createWriteStream("21million.rdf");
const gzipStream = zlib.createGzip();
gzipStream.pipe(writeStream);
const rl = readline.createInterface({
input: readStream,
output: gzipStream,
});
rl.on('line', (line) => {
gzipStream.write(`${line.toUpperCase()}\n`);
});
rl.on('close', () => {
console.log('done');
gzipStream.end();
});问题是这样的流,我收到了FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
所以问题是-我如何设置它,这样我就不会遇到OOM问题?
PS。我知道它可以用sed,awk,pert等来完成,但我需要用js来完成。
发布于 2019-09-06 21:51:02
这是由于Node.js处理Streams的方式造成的。它也称为backpressuring。当可读流提供数据的速度快于Writer可以使用的速度时,就会发生这种情况,这会导致内存使用量增加,因为数据必须保留在内存中,直到整个过程完成。
解决此问题的一种方法是使用Transform流,它通过管道处理数据转换。
下面的代码应该可以实现您想要实现的目标:
const stream = require('stream');
const transformStream = new stream.Transform({
writableObjectMode: true,
transform: (chunk, encoding, callback) => {
const chunkText = chunk.toString(encoding);
const modifiedChunkText = chunkText.toUpperCase(); // apply modifications to the text
callback(false, Buffer.from(modifiedChunkText, encoding));
}
});
readStream // reads from 21million.rdf.gz
.pipe(transformStream) // transforms data
.pipe(gzipStream) // writes to output file
.on('finish', () => {
console.log('done');
});https://stackoverflow.com/questions/57722343
复制相似问题