StreamReader打破特殊字符

时间:2019-05-30 15:40:46

标签: node.js encoding character-encoding fs

我正在尝试使用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个块来表示该字符。

我只是不知道如何解决它。通常,我只需要逐行处理它。也许我走错了方向?

1 个答案:

答案 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 */
} )

它对于交互式命令行输入/输出也很方便,但是您不在这里。