Взлом StreamReader по спецсимволу - PullRequest
1 голос
/ 30 мая 2019

Я пытаюсь прочитать файл в метеоритном приложении на сервере с 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 Ответ

1 голос
/ 30 мая 2019

Крошечные значения верхней отметки не сохраняют значительный объем оперативной памяти;значения по умолчанию что-то вроде 32k в любом случае.И попытка использовать верхнюю отметку для принудительного применения устаревшей операции getchar() означает злоупотребление ею.

В ядре node.js есть объект readline.Он принимает вывод из потока и разбивает его на строки. Документация предлагает несколько образцов .Это адаптировано из примеров не отлажено .

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

Это также удобно для ввода / вывода интерактивной строки команды, но вам здесь все равно.

...