繁体   English   中英

解压缩,转换和压缩回nodejs中的大文件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM