Вступление
В информатике файл - это ресурс, используемый для дискретной записи данных в запоминающее устройство компьютера. Node.js никоим образом не отменяет это и работает со всем, что считается файлом в вашей файловой системе.
Чтение файлов и ресурсов имеет множество применений:
- Статистика, аналитика и отчеты
- Машинное обучение
- Работа с большими текстовыми файлами или журналами
Иногда эти файлы могут быть абсурдно большими, в них хранятся гигабайты или терабайты, и их полное чтение неэффективно.
Возможность читать файл построчно дает нам возможность искать только релевантную информацию и останавливать поиск, как только мы нашли то, что ищем. Это также позволяет нам разбивать данные на логические части, как если бы файл был отформатирован в формате CSV.
Readline (с v0.12 и далее)
В Node.js есть собственный модуль для чтения файлов, который позволяет
нам читать построчно. Он был добавлен в 2015 году и предназначен для
чтения из любого Readable
одной строке за раз.
Этот факт делает его универсальным вариантом, подходящим не только для
файлов, но даже для ввода командной строки, такого как process.stdin
.
Документацию по readline
можно найти
здесь .
Поскольку readline
- это собственный модуль. Вам не нужно использовать
npm
для любого другого менеджера пакетов, чтобы добавить его, просто
require
:
const readline = require('readline');
и тебе хорошо идти!
Поскольку readline
должен поставляться с потоком, мы должны сначала
создать его, используя другой собственный модуль - fs
:
const fs = require('fs');
Следующим шагом будет создание объекта, который будет читать из потока с
помощью функции createInterface()
:
const readInterface = readline.createInterface({
input: fs.createReadStream('/path/to/file'),
output: process.stdout,
console: false
});
Убедитесь, что вы заменили /path/to/file
на фактический путь к файлу в
вашей файловой системе.
После завершения подготовки - построчное чтение файла и вывод его содержимого на консоль можно выполнить следующим образом:
readInterface.on('line', function(line) {
console.log(line);
});
Здесь мы, по сути, говорим, что всякий раз, когда line
происходит в
readInterface
оно должно вызывать нашу функцию и передавать ей
содержимое, прочитанное из потока. В нашем случае мы не хотим слишком
усложнять и просто выводим это на консоль.
Line-Reader
После подробного объяснения того, как можно построчно читать файл с помощью собственного модуля Node.js, давайте взглянем на его более короткую версию с использованием модуля чтения строк с открытым исходным кодом от npm.
Поскольку это неродной модуль, нам нужно убедиться, что мы правильно
инициализировали проект npm init
а затем установили его:
$ npm install --save line-reader
Это установит зависимость и добавит ее в файл package.json
Как только это будет сделано, построчное чтение файла аналогично
предыдущему примеру, только без создания readInterface
посередине:
const lineReader = require('line-reader');
lineReader.eachLine('/path/to/file', function(line) {
console.log(line);
});
Очень полезная функция здесь - прекратить чтение, когда какое-то условие
выполняется. Это достигается простым возвратом false
из функции
обратного вызова.
Например, мы можем читать файл построчно, пока не найдем строку, в которой есть слово «STOP»:
lineReader.eachLine('path/to/file', function(line) {
console.log(line);
if (line.includes('STOP') {
return false; // stop reading
}
});
Есть несколько другой подход, который использует два вложенных обратных вызова и синтаксис, который может показаться более естественным разработчикам Java:
lineReader.open('/path/to/file', function(reader) {
if (reader.hasNextLine()) {
reader.nextLine(function(line) {
console.log(line);
});
}
});
Здесь мы используем open()
, которая не предоставляет нам строки из
файла мгновенно, а скорее дает нам reader
. У него есть собственный
набор функций, таких как hasNextLine()
и nextLine()
которые
позволяют нам немного больше контролировать процесс чтения файла
построчно в Node.js.
N-строки
Другой синтаксис предоставляется модулем npm
n-readlines
:
Установим:
$ npm install --save n-readlines
И потребовать это:
const lineByLine = require('n-readlines');
Чтобы иметь возможность читать из файла, мы должны создать новый объект, указав путь к нашему файлу в качестве аргумента:
const liner = new lineByLine('/path/to/file');
Получение строк из файла осуществляется вызовом next
функции:
let line;
while (line = liner.next()) {
console.log(line);
}
Интересная функция модуля n-readlines
reset()
. Он сбрасывает
указатель и запускает процесс чтения с самого начала файла.
Примечание : работает только в том случае, если конец не достигнут.
Распространенные ошибки
Распространенной ошибкой при построчном чтении файла в Node.js является чтение всего файла в память с последующим разделением его содержимого по разрывам строк.
Вот неправильный пример, который может перегрузить вашу систему, если вы предоставите ему достаточно большой файл:
require('fs').readFileSync('/path/to/file', 'utf-8').split(/\r?\n/).forEach(function(line) {
console.log(line);
});
На первый взгляд кажется, что результат для этого подхода такой же, как и для предыдущих, и на самом деле он отлично работает для небольших файлов. Но продолжайте и попробуйте поработать с большим. Это определенно не то, что вы хотите видеть в своей производственной системе.
Заключение
Существует несколько способов чтения файла построчно в Node.js, и выбор подходящего подхода полностью зависит от программиста.
Вы должны подумать о размере файлов, которые вы планируете обрабатывать, требованиях к производительности, стиле кода и модулях, которые уже есть в проекте. Обязательно протестируйте некоторые угловые случаи, такие как огромные, пустые или несуществующие файлы, и вам будет хорошо использовать любой из предоставленных примеров.