Чтение и запись CSV в Node.js

CSV (Comma-Separated Values) — простой текстовый формат для хранения табличных данных. В Node.js CSV-файлы удобно читать как для настройки приложений, так и для передачи больших наборов данных между сервисами. Ниже — практическое руководство: подготовка проекта, варианты чтения (синхронно, потоково) и использование пакета fast-csv для надёжного парсинга.
Что нужно для примеров
Важно: инструкция рассчитана на среду с установленным Node.js. Проверьте версию командой:
node -vЕсли Node.js не установлен — установите официальным инсталлятором с nodejs.org.
Создайте рабочую папку и файл для примеров:
mkdir parse-csv
cd parse-csv
touch parseCSV.jsТеперь можно переходить к практическим примерам.
Использование модуля fs
Модуль fs (file system) предоставляет синхронные и асинхронные операции для чтения и записи файлов.
Чтение всего файла целиком
fs.readFile() — асинхронный и неблокирующий метод; readFileSync() — синхронный и блокирует выполнение. Для CSV, особенно больших, предпочтительнее асинхронный вариант:
const fs = require('fs');
fs.readFile('csvdemo.csv', 'utf8', function (err, data) {
if (err) {
console.error('Ошибка чтения файла:', err);
return;
}
// Здесь data — содержимое файла в виде строки
// Разбор строки в простейшем виде:
const rows = data.split('\n').map(r => r.split(','));
console.log(rows);
});Примечание: чтение целиком удобно для небольших файлов. При больших объёмах памяти это может привести к сильному потреблению памяти и замедлению приложения.
Чтение построчно (потоковое чтение)
Для больших CSV используйте потоки: fs.createReadStream() плюс модуль readline или парсер. Это экономит память, так как данные обрабатываются по частям.
const fs = require('fs');
const readline = require('readline');
const stream = fs.createReadStream('./csvdemo.csv');
const rl = readline.createInterface({ input: stream });
let data = [];
rl.on('line', (row) => {
// В этом простом примере мы разделяем по запятой
data.push(row.split(','));
});
rl.on('close', () => {
console.log(data);
});Важно: простое split(‘,’) не корректно для всех CSV — строки с кавычками, запятые внутри полей, экранирование и разные разделители сломают такой парсер. Для реальных данных используйте специализированную библиотеку.
Использование fast-csv
fast-csv — популярная npm-библиотека для парсинга и форматирования CSV. Она корректно обрабатывает кавычки, экранирование, разные разделители и заголовки.
Установка:
npm init -y
npm i fast-csvПример чтения CSV с заголовками:
const fs = require('fs');
const csv = require('fast-csv');
const data = [];
fs.createReadStream('./csvdemo.csv')
.pipe(csv.parse({ headers: true }))
.on('error', error => console.error(error))
.on('data', row => data.push(row))
.on('end', () => console.log(data));Пояснения:
- headers: true — указывает, что первая строка файла содержит имена колонок. Если первой строки нет, используйте headers: false или передайте массив заголовков.
- Парсер обрабатывает корректно кавычки, пустые поля, разные разделители (опция delimiter).
Пример записи CSV с fast-csv
const fs = require('fs');
const csv = require('fast-csv');
const writeStream = fs.createWriteStream('out.csv');
const rows = [
{ name: 'Иван', age: 30 },
{ name: 'Мария', age: 25 }
];
csv.write(rows, { headers: true }).pipe(writeStream);Этот код создаст файл out.csv с заголовками name и age.
Когда не стоит писать свой парсер
- Данные могут содержать запятые внутри полей, кавычки, переводы строк в значениях или различные кодировки. Ручной split(‘,’) не устойчив.
- Если CSV формируется внешним сервисом, формат может меняться: лучше использовать пакет, поддерживающий опции и экранирование.
- Для больших файлов нужна потоковая обработка — простое чтение в память опасно.
Альтернативные библиотеки
- csv-parser — лёгкая потоковая библиотека, хорошо подходит для простого парсинга.
- papaparse — популярна в браузере; есть и серверные сборки.
- csv-parse (из пакета csv) — мощный парсер от community, поддерживает множество опций.
Выбор зависит от требований: производительность, поддержка потоков, гибкость опций.
Чек-лист инженера перед выбором подхода
- Оцените размер файлов: если >50 МБ, предпочитайте потоковую обработку.
- Проверьте формат входных CSV: есть ли заголовки, какие разделители, есть ли кавычки и переводы строк.
- Нужно ли сохранять порядок строк? Некоторые парсеры возвращают объекты асинхронно.
- Требуется ли валидация/нормализация данных во время чтения?
- Нужна ли высокая производительность (например, многопоточность или worker threads)?
Критерии приёмки
- Приложение корректно читает CSV с заголовками и без (опция в тестовых данных).
- Парсер правильно обрабатывает поля с кавычками и запятыми внутри значения.
- Обработка больших файлов не приводит к росту потребления памяти (тест с файлом >100 МБ).
- При некорректном входе приложение возвращает понятную ошибку и не падает.
Небольшая шпаргалка (cheat sheet)
- Быстрое чтение малого файла:
- fs.readFile
- Потоковое чтение больших файлов:
- fs.createReadStream + readline или csv-парсер
- Варианты опций fast-csv:
- headers: true | false
- delimiter: ‘,’ | ‘;’ | ‘\t’
- ignoreEmpty: true
Пример опций с другим разделителем:
fs.createReadStream('./csvdemo.csv')
.pipe(csv.parse({ headers: true, delimiter: ';' }))
.on('data', row => /* ... */);Короткий глоссарий (одно предложение на термин)
- CSV — текстовый формат для табличных данных, разделённых символом (обычно запятая).
- Stream (поток) — объект для построчной или частичной обработки данных, не загружая всё в память.
- Pipe — метод соединения потоков, обеспечивает передачу данных из одного потока в другой.
- Парсер — библиотека, которая корректно разбирает формат CSV с учётом кавычек и экранирования.
Рекомендации по тестированию
- Тестируйте с файлами, содержащими:
- пустые поля
- кавычки внутри значения: “””quoted”””
- запятые внутри поля: “Smith, John”
- строки с переводами строк внутри полей
- Покройте тестами сценарию отказа: отсутствует файл, неправильная кодировка, повреждённая строка.
Краткое резюме
Используйте fs.readFile или fs.readFileSync для небольших файлов и для простых сценариев. Для производительности и корректного разбора реальных CSV-файлов лучше применять потоковую обработку (fs.createReadStream) вместе с библиотеками вроде fast-csv, csv-parser или csv-parse. Всегда тестируйте парсер на «грязных» данных: кавычки, запятые внутри полей и переводы строк.
Важно: при работе с персональными данными соблюдайте требования конфиденциальности и законодательство о защите данных.
Похожие материалы
YouTube Music на Windows — PWA и десктопные клиенты
Family Pairing в TikTok — как включить контроль
Apple Pay не работает — как быстро исправить
Проверка и очистка использования диска Docker
Как исправить ошибки Hulu на Xbox One