Node.js 为什么nodejs写入流会导致内存消耗增加?

Node.js 为什么nodejs写入流会导致内存消耗增加?,node.js,Node.js,我正在NodeJS中读取一个45Mb的文本文件,并对其中的每个字符进行处理 我的脚本的第一个版本从原始文件中提取了一个字符,将其存储在累加器变量(result+=char)中,最后将结果保存在文本文件中。这不起作用,因为文件太大了,我在RAM上放了太多数据,所以我得到了一个错误:Javascript堆内存不足。我决定使用写入流,这样我就可以一次将数据直接写入一个聊天盘,这样就可以解决这个问题: fs = require('fs'); var proportion = 2; var c = '

我正在NodeJS中读取一个45Mb的文本文件,并对其中的每个字符进行处理

我的脚本的第一个版本从原始文件中提取了一个字符,将其存储在累加器变量(result+=char)中,最后将结果保存在文本文件中。这不起作用,因为文件太大了,我在RAM上放了太多数据,所以我得到了一个错误:Javascript堆内存不足。我决定使用写入流,这样我就可以一次将数据直接写入一个聊天盘,这样就可以解决这个问题:

fs = require('fs');

var proportion = 2;

var c = '';

fs.readFile('./concat/all.txt', 'utf8', function (err,data) {
    if (err) {
        return console.log(err);
    }

    var h = parseInt(Math.sqrt(data.length / proportion));
    var w = parseInt(h * proportion);

    console.log(w, h);

    var wstream = fs.createWriteStream('output.txt');


    var lineCount = 0;
    for(var x = 0; x < data.length; x++) {

        if(data.charCodeAt(x) === 32 && x > 0 && data.charCodeAt(x - 1) === 32)
            continue;

        if(data.charCodeAt(x) === 10 && x > 0 && data.charCodeAt(x - 1) === 10)
            continue;

        c = (data.charCodeAt(x) === 10 || data.charCodeAt(x) === 13 || data.charCodeAt(x) === 9) ? " " : data.charAt(x);
        lineCount++;
        if(lineCount > w) {
            c += "\n";
            lineCount = 0;
        }


        wstream.write(c);
    }

    wstream.end();

});
fs=require('fs');
var比例=2;
var c=“”;
fs.readFile('./concat/all.txt',utf8',函数(err,data){
如果(错误){
返回console.log(err);
}
var h=parseInt(Math.sqrt(data.length/proportion));
var w=parseInt(h*比例);
控制台日志(w,h);
var wstream=fs.createWriteStream('output.txt');
var-lineCount=0;
对于(var x=0;x0&&data.charCodeAt(x-1)==32)
继续;
if(data.charCodeAt(x)==10&&x>0&&data.charCodeAt(x-1)==10)
继续;
c=(data.charCodeAt(x)==10 | | data.charCodeAt(x)==13 | | data.charCodeAt(x)==9)?“”:data.charAt(x);
lineCount++;
如果(行数>w){
c+=“\n”;
行数=0;
}
wstream.write(c);
}
wstream.end();
});
但是,我还是遇到了一个内存不足的错误。如果我注释
wstream.write(c)
,脚本运行时不会出现问题。为什么?

流,流,流。。。 限制输入/输出:

以块的形式流化输入,暂停每个块的流,解析和操作当前块的每个字符,并将其写入输出

然后您可以继续输入流以继续下一个,重复直到完成


使用
createReadStream
&
createWriteStream

以下是代码(使用
64MB
文件成功测试)

const fs=require('fs'))
var-w;var charCount=0;风险价值比例=2
//:此步骤是填充“w”所必需的
fs.readFile('input.txt','utf8',函数(err,data){
if(err){return console.log(err)}
设h=parseInt(Math.sqrt(data.length/proportion))
w=parseInt(h*比例);数据=未定义;
log(“[+]正在启动(w:”,w“)”);EMX()
});
//:这是魔法
函数EMX(){
const I=fs.createReadStream('input.txt')
常量O=fs.createWriteStream('output.txt')
I.on('end',()=>{console.log(“[+]操作已完成”)})
I.on('数据',(块)=>{
I.pause();让数据=chunk.toString()
对于(varx=0;x0&&data.charCodeAt(x-1)==32)是否继续
如果(data.charCodeAt(x)==10&&x>0&&data.charCodeAt(x-1)==10)继续
c=(data.charCodeAt(x)==10 | | data.charCodeAt(x)==13 | | data.charCodeAt(x)==9)?“”:data.charAt(x)
如果(charCount>w){c+=“\n”;charCount=0;}charCount++
O.write(c)
}
一、简历
})
}

我猜是因为for循环可能在1秒内完成,而编写仍然需要100秒。所以基本上它仍然都在记忆中。。。您需要降低
wstream.write(c)的速度呼叫关闭。。。。我甚至会说,第一个字符只有在退出readFile回调后才被写入。在这之前,所有你想写的数据都被缓冲在内存中。那么呢?我的解决方案是否如您所希望的那样跨平台?
const fs = require('fs')
var w;  var charCount = 0;  var proportion = 2
//:This step was required to populate 'w'
fs.readFile('input.txt', 'utf8', function (err,data) {
 if(err){return console.log(err)}
 let h = parseInt(Math.sqrt(data.length / proportion))
 w = parseInt(h * proportion); data = undefined;
 console.log('[+] starting  ( w:',w,')'); EMX()
});
//:Here is the magick
function EMX(){
 const I = fs.createReadStream('input.txt')
 const O = fs.createWriteStream('output.txt')
 I.on('end',()=>{console.log("[+] operation completed")})
 I.on('data', (chunk) => {
  I.pause(); let data = chunk.toString()
  for(var x=0;x<data.length;x++){
   if(data.charCodeAt(x) === 32 && x > 0 && data.charCodeAt(x - 1) === 32) continue
   if(data.charCodeAt(x) === 10 && x > 0 && data.charCodeAt(x - 1) === 10) continue
   c = (data.charCodeAt(x) === 10 || data.charCodeAt(x) === 13 || data.charCodeAt(x) === 9) ? " " : data.charAt(x)
   if(charCount>w){c+="\n";charCount=0;} charCount++
   O.write(c)
  }
  I.resume()
 })
}