【问题标题】:StreamReader breaking on special characterStreamReader 打破特殊字符
【发布时间】:2019-05-31 00:52:12
【问题描述】:

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

我只是不知道如何绕过它。一般来说,我只需要逐行处理它。也许我走错路了?

【问题讨论】:

    标签: node.js encoding character-encoding fs


    【解决方案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 */
    } )
    

    交互式命令行输入/输出也很方便,但你不必关心这里。

    【讨论】:

    • 哦,看起来不错。据 ram:我有大约 600-1000 MB 的文件。逐个字符不重要,逐行重要!我会在几个小时内尝试一下。感谢您的回答!
    • 完美运行。非常喜欢!
    猜你喜欢
    • 2012-04-25
    • 2019-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多