我正在NodeJS中读取一个45Mb的文本文件,并对其上的每个字符进行一些处理。
我的脚本的第一个版本从原始文件中获取了一个char,将它存储在一个accumulator变量(result + = char)中,然后将结果保存到一个文本文件中。这不起作用,因为文件太大我在RAM上放了太多数据,所以我收到一个错误: Javascript Heap out of memory 。我决定使用写入流,这样我就可以在一次聊天时直接将数据写入磁盘,这样可以解决问题:
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();
});
但是,我仍然遇到内存不足错误。如果我评论wstream.write(c)
,脚本运行没有问题。为什么呢?
答案 0 :(得分:1)
限制I / O:
以块的形式传输输入,为每个块暂停流,解析&amp;操纵当前块的每个字符并将其写入输出。
然后你可以恢复输入流继续下一个,重复直到完成。
我使用createReadStream
&amp; amp;来限制您的代码是没有问题的createWriteStream
以下是代码(使用64MB
文件成功测试)
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()
})
}