![](/img/trans.png)
[英]Big JSON file - how to compress in the server and decompress in the client side?
[英]Decompress, transform and compress back big file in nodejs
我有一个很大的文件(gzip压缩为30Gb,gunzip压缩为〜300Gb),它是rdf压缩文件,我需要逐行处理并将gzip压缩回另一个文件。 所以这是我目前所拥有的(测试文件压缩为〜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中完成。
这是由于Node.js处理Streams的方式引起的。 也称为背压 。 当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');
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.