Поток на чтение и запись




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

Однако в Node.js есть отдельный модуль для работы с потоками — stream.

Duplex-поток реализует интерфейсы потока на чтение и потока на запись. Такие потоки используются:

● в TCP-сокетах — транспортный протокол передачи данных по сети;

● в потоках сжатия данных, шифрования данных и т. д.

Мы рассмотрим один из видов потока на чтение и запись (и самый распространённый) — поток Transform. Он предназначен для преобразования порции считанных или полученных данных и отправки их дальше по цепочке.

Допустим, в одном файле мы храним неизменные, необработанные логи в том виде, в котором их получаем. Но эти данные требуются нам и в обработанном виде. Для решения такой задачи вполне подойдёт поток Transform.

Разобьём задачу на шаги:

  1. Считать данные из файла.
  2. Преобразовать данные.
  3. Вывести данные в терминал.

Соединить все три шага мы можем посредством метода pipe(), который доступен в объекте любого потока. Этот метод предназначен для создания цепочек потоков и передачи по ней данных.

Читать данные из файла, используя потоки, мы уже умеем.

const fs = require('fs'); const readStream = new fs.ReadStream('./access.log', 'utf8');

 

Теперь создадим и настроим поток Transform.

const { Transform } = require('stream'); const transformStream = new Transform({ transform(chunk, encoding, callback) { const transformedChunk = chunk.toString().replace(/127.0.0.1/g, ''); this.push(transformedChunk); callback(); } });

 

Здесь мы создаём экземпляр класса Transfrom и передаём в конструктор метод transform. Этот метод и будет выполнять основную работу — преобразовывать данные и отправлять их дальше.

Допустим, нам надо удалить из логов любое упоминание об localhost. Делаем это посредством метода replace и простого регулярного выражения.

Вызовом метода this.push мы фиксируем изменения, а затем через вызов callback отправляем данные на выход потока.

Функция callback также фиксирует изменения и сразу отправляет данные на выход. Для этого надо передать в неё эти данные вторым аргументом. Первым аргументом она принимает объект ошибки.

callback(null, transformedChunk);

 

Однако если фиксировать изменения методом this.push, то у нас появится возможность делать это несколько раз перед отправкой данных на выход. Это позволит, например, продублировать какую-то часть данных или изменять их поэтапно.

Теперь осталось вывести изменённые данные в терминал. Для этого используем вышеупомянутый метод pipe(). Соединяем поток на чтение с трансформирующим потоком, затем отправляем данные в поток на вывод process.stdout:

readStream.pipe(transformStream).pipe(process.stdout);

 

Здесь появляется незнакомая нам сущность — process.stdout. Это интерфейс стандартного модуля process для работы с потоком вывода stdout. В нашем случае, отправляя данные в такой поток, мы выводим их в терминал. Кроме стандартного потока вывода, есть также стандартный поток ввода stdin и стандартный поток вывода ошибок stderr. Подробнее о потоках — в этой статье.

Итоговый код:

const fs = require('fs'); const readStream = new fs.ReadStream('./access.log', 'utf8'); const { Transform } = require('stream'); const transformStream = new Transform({ transform(chunk, encoding, callback) { const transformedChunk = chunk.toString().replace(/127.0.0.1/g, ''); this.push(transformedChunk); callback(); } }); readStream.pipe(transformStream).pipe(process.stdout);

 

Итак, в этом уроке мы рассмотрели много важных понятий, касающихся не только разработки на Node.js, но и веб-разработки в целом. Работа с файлами, кодировки, двоичные данные, потоки — это лишь малая часть того интересного мира, который мы изучаем. Важно тренироваться и экспериментировать с пройденным материалом, пытаться адаптировать предоставленные знания под конкретные задачи. Только закрепляя теоретические знания на практике, можно сделать их устойчивой и неотъемлемой частью профессионализма.

Глоссарий

Буфер — участок памяти, в котором данные хранятся в ожидании обработки.

Класс Buffer — это глобальный класс, позволяющий работать с потоками двоичных данных.

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

Потоки — это абстракция для «порционной» работы с данными, которые перемещаются из одного места в другое.

Файловый дескриптор — это неотрицательное целое число, которое возвращает ядро системы процессу при создании нового потока ввода-вывода.

Файловая система — это порядок, который определяет способ организации, хранения и именования данных на цифровых носителях информации.

Дополнительные материалы

  1. Официальная документация.
  2. Статья «Компьютерная память».
  3. Статья «О кодировках и кодовых страницах».
  4. Статья «И снова о Unicode».
  5. Класс Buffer в официальной документации.
  6. Флаги для работы с файловой системой.
  7. Статья «Что такое файловый дескриптор простыми словами».
  8. Статья «Стандартные потоки ввода-вывода».

Используемые источники

  1. Официальная документация.
  2. Статья «И снова о Unicode».
  3. Статья Do you want a better understanding of Buffer in Node.js? Check this out.

 

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2021-12-15 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: