我有相当大的压缩后的rdf文件(压缩后为30Gb,压缩后为约300Gb),我需要逐行处理并将gzip压缩回另一个文件。因此,这就是我目前拥有的内容(测试中的file压缩了〜150Mb)
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中完成。
答案 0 :(得分:0)
这是由于Node.js处理Streams的方式所致。也称为backpressuring。当Readable流提供的数据快于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');
});