我正在尝试使用fs
在服务器上的流星应用中读取文件。
我的目标:
我想处理一个很大的文件。因此,我需要逐行读取它,以保持内存使用量不变。
我的方法:
我正在创建一个streamReader并为每个字符处理文件,将其保存到新字符串中,直到得到\n
,然后将其传递给processLine(line)
函数。
我的测试文件:
F1;F2
12;abäde
我的代码:
我已评论所有超出问题范围的内容。无论如何发布它,以防万一有人对我有完全不同的方式。
const fs = require('fs');
// ...
let streamReader = fs.createReadStream(path, { highWaterMark: 1});
let line = "";
streamReader.on('data', function(chunk) {
console.log(chunk)
// line += chunk;
// if (chunk == "\n") {
// processLine(line);
// line = "";
// }
});
streamReader.on('end', function() {
processLine(line);
});
processLine = (line) => {
console.log(line);
}
上面代码的输出:
F
1
;
F
2
1
2
;
a
b
�
�
d
e
文档中的任何一个都说默认编码为utf8
,字符ä
打印为�
。
指定如下所示的编码时输出:
fs.createReadStream(path, { highWaterMark: 1, encoding: "utf8 }
F
1
;
F
2
1
2
;
a
b
到达ä
时中断。我认为发生这种情况是因为它需要2个块来表示该字符。
我只是不知道如何解决它。通常,我只需要逐行处理它。也许我走错了方向?
答案 0 :(得分:1)
高水位标记的微小值不会节省大量RAM;不管怎样,默认值都是32k。而且,尝试使用高水位标记强制执行旧的getchar()
操作就是滥用它。
There's a readline
object in core node.js。它接受流的输出并将其拆分为行。 The documentation offers some samples。这是根据未调试的示例改编的。
const fs = require('fs')
const readline = require('readline')
const rl = readline.createInterface(
{
input: fs.createReadStream(path),
crlfDelay: Infinity
})
rl.on('line', function (line) {
console.log(`A line: ${line}`);
})
rl.on('close', function () {
/* file completely processed */
} )
它对于交互式命令行输入/输出也很方便,但是您不在这里。