Skip to main content

Типи потоків

1. Загальне визначення

Потік (Stream) - це абстракція, що дозволяє читати чи записувати дані поступово, по шматках (chunks), не завантажуючи все в пам'ять одразу.

Кожен потік - це об'єкт, який реалізує інтерфейс EventEmitter (він генерує події на кшталт 'data', 'end', 'error', 'finish').

2. Основні типи потоків у Node.js

ТипПризначенняПриклад використанняОсновні методи/події
ReadableЧитання данихЧитання файлів, HTTP-запитів, stdin.on('data'), .pipe(), .read()
WritableЗапис данихЗапис у файл, HTTP-відповідь, stdout.write(), .end(), .on('finish')
DuplexДвосторонній потік (читання + запис)TCP-сокети, WebSocket.write(), .read(), .pipe()
TransformDuplex + перетворення даних "на льоту"Стиснення (zlib), шифрування (crypto).pipe(), .transform()

Readable Stream (потік для читання)

Це джерело даних - потік, з якого читають.

Приклади:

  • читання файлу через fs.createReadStream(),
  • тіло HTTP-запиту (req у http.createServer()),
  • потік введення (process.stdin).

Приклад:

javascript
const fs = require('fs'); const readable = fs.createReadStream('file.txt', 'utf8'); readable.on('data', chunk => { console.log('Отримано шматок:', chunk.length); }); readable.on('end', () => { console.log('Читання завершено'); });

Потік читає дані поступово й викликає подію 'data' для кожного чанка.

Writable Stream (потік для запису)

Це приймач даних - потік, у який записують.

Приклади:

  • запис у файл через fs.createWriteStream(),
  • надсилання відповіді (res) в HTTP-сервері,
  • виведення в консоль (process.stdout).

Приклад:

javascript
const fs = require('fs'); const writable = fs.createWriteStream('output.txt'); writable.write('Перший рядок\n'); writable.write('Другий рядок\n'); writable.end('Файл записано'); writable.on('finish', () => { console.log('Запис завершено'); });

Потік приймає дані частинами через .write(), і повідомляє про завершення через подію 'finish'.

Duplex Stream (двонаправлений потік)

Це потік, який може одночасно читати й записувати дані. Він поєднує можливості Readable і Writable.

Приклади:

  • мережеві з'єднання (net.Socket),
  • WebSocket-з'єднання,
  • потік TCP (один потік читає й пише).

Приклад:

javascript
const { Duplex } = require('stream'); const duplex = new Duplex({ read(size) { this.push('дані з duplex\n'); this.push(null); }, write(chunk, encoding, callback) { console.log('Записано:', chunk.toString()); callback(); } }); duplex.on('data', chunk => console.log('Читання:', chunk.toString())); duplex.write('Hello Duplex!');

Duplex корисний для двостороннього обміну (наприклад, сокети, тунелі, протоколи).

Transform Stream (трансформаційний потік)

Це особливий вид Duplex-потоку, який перетворює дані "на льоту" під час проходження.

Приклади:

  • стиснення (zlib.createGzip()),
  • шифрування (crypto.createCipher()),
  • перетворення тексту (наприклад, у верхній регістр).

Приклад:

javascript
const { Transform } = require('stream'); const upperCase = new Transform({ transform(chunk, encoding, callback) { this.push(chunk.toString().toUpperCase()); callback(); } }); process.stdin.pipe(upperCase).pipe(process.stdout);

Усе, що ти введеш у консоль, виведеться у верхньому регістрі.

3. Взаємодія потоків

Зазвичай потоки з'єднують за допомогою .pipe():

javascript
const fs = require('fs'); const zlib = require('zlib'); fs.createReadStream('file.txt') .pipe(zlib.createGzip()) // Transform stream (стиснення) .pipe(fs.createWriteStream('file.txt.gz')); // Writable stream

Тут:

  • createReadStream → джерело даних (Readable)
  • createGzip → перетворення (Transform)
  • createWriteStream → приймач (Writable)

Потоки з'єднуються як конвеєр (pipeline), передаючи дані частинами без блокування пам'яті.

4. Події та методи потоків

Тип потокуКлючові подіїОсновні методи
Readable'data', 'end', 'error'.read(), .pipe(), .pause(), .resume()
Writable'drain', 'finish', 'error'.write(), .end()
Duplexпоєднує обидва набори.read(), .write()
Transform'data', 'finish', 'error'.pipe(), .transform()

5. Де використовуються ці типи потоків

МодульВикористовує потоки
fsчитання/запис файлів (createReadStream, createWriteStream)
httpreq і res - потоки (Readable/Writable)
zlibстиснення / розпакування (Transform)
cryptoшифрування / хешування (Transform)
netTCP-з'єднання (Duplex)
processstdin, stdout, stderr - потоки

Підсумок

ТипПризначенняПриклад
ReadableДжерело даних (читання)fs.createReadStream(), req
WritableПриймач даних (запис)fs.createWriteStream(), res
DuplexЧитання + запис одночасноnet.Socket, WebSocket
TransformЧитання + запис + перетворенняzlib.createGzip(), crypto.createCipher()

Висновок:

У Node.js існує чотири типи потоків - Readable, Writable, Duplex і Transform.

Вони дозволяють:

  • читати, записувати й перетворювати дані поступово,
  • працювати з великими файлами й мережевими потоками ефективно,
  • і будувати ланцюжки обробки даних без завантаження всієї інформації в пам'ять.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.