Чтение больших файлов построчно в Node.js: эффективные методы

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

JS
Скопировать код
const readline = require('readline');
const fs = require('fs');

const lineReader = readline.createInterface({
    input: fs.createReadStream('file.txt')
});

lineReader.on('line', (line) => console.log(line));

В примере выше демонстрируется, как за счет возможностей модулей readline и fs реализовать потоковую обработку текстового файла на Node.js. Пройдясь по каждой его строке, мы выводим ее на экран. Вместо 'file.txt' нужно указать актуальный путь к файлу.

Кинга Идем в IT: пошаговый план для смены профессии

Правильная обработка переносов строк и больших файлов

Работа с различными типами переносов строк

При обработке файлов с разнообразными форматами окончания строк либо работы с потоками данных выбор значения crlfDelay как Infinity оказывается особенно полезным. Это помогает интерпретировать каждую последовательность символов \r\n как единый перенос строки.

JS
Скопировать код
const lineReader = readline.createInterface({
  input: fs.createReadStream('file.txt'),
  crlfDelay: Infinity
});
Подробнее об этом расскажет наш спикер на видео
skypro youtube speaker

Асинхронное чтение для эффективной обработки больших файлов

Объемные файлы при неправильной обработке могут привести к исчерпанию памяти. Для избежания этого проблему решает асинхронная обработка каждой строки файла с помощью асинхронных возможностей потоков Node.js.

JS
Скопировать код
lineReader.on('line', async (line) => {
  await processLine(line); // функция processLine должна быть максимально эффективна
});

Обеспечение чтения до последней строки

Для гарантированного прочтения каждой строки из большого файла, включая последнюю, которая может и не завершаться переносом строки, следует использовать событие close.

JS
Скопировать код
lineReader.on('close', () => {
  console.log('Весь файл прочитан, от первой до последней строки.');
});

Современный метод итерации в Node.js

В Node.js версии 11.4 и более поздних встроен цикл for await...of, весьма изящно решающий задачу итерации по строкам файла.

JS
Скопировать код
const rl = readline.createInterface({
  input: fs.createReadStream('file.txt'),
  crlfDelay: Infinity
});

for await (const line of rl) {
  console.log(`Получена строка: ${line}`);
}

Визуализация

Представить чтение файла построчно с помощью Node.js можно так:

Markdown
Скопировать код
📜 == Река (Файл)
🚡 == Гондола (Поток)

Каждая строка файла — это проезд гондолы через реку:

JS
Скопировать код
const readline = require('readline');
const fs = require('fs');

const rl = readline.createInterface({
  input: fs.createReadStream('file.txt')
});

rl.on('line', (line) => {
  console.log(`Гондола доставляет: ${line}`);
});

Этот процесс можно схематически изобразить:

Markdown
Скопировать код
🚡 Старт | 📜 Строка 1 | 🚡 Финиш
🚡 Старт | 📜 Строка 2 | 🚡 Финиш
// и так до последней строки

Каждый проезд гондолы — это активация события .on('line', ...), считывающего строку файла, что делает процесс крайне эффективным.

Решение распространенных проблем

Важность выбора правильной текстовой кодировки

Указание правильной кодировки, например, 'utf-8', избавляет от проблем с неправильным отображением спецсимволов или текста.

JS
Скопировать код
const lineReader = readline.createInterface({
  input: fs.createReadStream('file.txt', { encoding: 'utf-8' }) // чтобы говорить на одном языке
});

Приоритет нативных модулей

Несмотря на то что readline предпочтительнее использовать, в специфических случаях могут пригодиться пакеты вроде Lazy и event-stream.

Обязательная обработка ошибок

При настройке интерфейса readline не забывайте об обработке ошибок:

JS
Скопировать код
lineReader.on('error', (error) => {
  console.error(`Упс! Произошла ошибка: ${error}`);
});

Возможность синхронного чтения

Вопреки эффективности асинхронного чтения, в более простых случаях может быть уместно использовать fs.readFileSync. Это позволяет разделить текст на строки для последующей обработки:

JS
Скопировать код
const allLines = fs.readFileSync('file.txt', { encoding: 'utf-8' }).split(/\r?\n/);
allLines.forEach((line) => {
  console.log(line); // строки, как партнеры в танце
});

Полезные материалы

  1. File system | Документация Node.js v21.6.1официальная документация по Node.js по fs.createReadStream.
  2. Readline | Документация Node.js v21.6.1 — подробная инструкция из документации Node.js по использованию readline для построчного чтения файлов.
  3. Understanding Streams in Node.js – NodeSource — статья о теории и практике работы с потоками в Node.js.
  4. javascript – Чтение файла по одной строке в node.js? – Stack Overflowобсуждение на Stackoverflow, где можно найти практические решения и мнения сообщества разработчиков.
  5. line-reader – npm — страница npm-библиотеки line-reader, предназначенной для построчного чтения файлов в Node.js.
  6. event-stream – npm — страница npm с event-stream, которая помогает в обработке больших файлов в Node.js без ошибок.
  7. Лучшие практики и советы по Node.js от экспертов | Toptal® — сборник наилучших практик и советов для разработчиков на Node.js.
Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Какой модуль следует использовать для построчного чтения файла в Node.js?
1 / 5