Пошук уроків, статей та іншого контенту
Створите консольні програми, що читають дані з process.stdin і записують результати в process.stdout.
stdin і stdoutКонсольна програма може:
отримувати дані зі стандартного введення — process.stdin;
записувати дані у стандартне виведення — process.stdout.
У Node.js обидва об’єкти є потоками:
process.stdin — потік читання;
process.stdout — потік запису.
Потік обробляє дані частинами. Такі частини називають фрагментами або чанками. Навіть якщо користувач вводить один рядок, Node.js може отримати його не як один великий рядок, а як послідовність фрагментів.
process.stdinДля читання даних можна слухати подію data:
process.stdin.on("data", (chunk) => {
console.log("Отримано:", chunk);
});Параметр chunk за замовчуванням має тип Buffer. Buffer — це об’єкт для роботи з двійковими даними.
Щоб працювати зі звичайним текстом, потрібно перетворити фрагмент на рядок:
process.stdin.on("data", (chunk) => {
const text = chunk.toString();
process.stdout.write(`Ви ввели: ${text}`);
});Запустіть програму, введіть текст і натисніть Enter. Завершити введення в терміналі можна комбінацією Ctrl+D у Linux та macOS або Ctrl+Z, а потім Enter у Windows.
Замість ручного виклику toString() можна вказати кодування для потоку:
process.stdin.setEncoding("utf8");
process.stdin.on("data", (chunk) => {
process.stdout.write(`Отримано: ${chunk}`);
});Після виклику setEncoding("utf8") змінна chunk буде рядком.
Кодування utf8 дає змогу правильно працювати з українськими та іншими Unicode-символами.
process.stdoutДля запису даних використовується метод process.stdout.write():
process.stdout.write("Привіт, Node.js!");
process.stdout.write("\n");
process.stdout.write("Це новий рядок.\n");Метод write():
приймає рядок;
не додає перенесення рядка автоматично;
може викликатися кілька разів.
На відміну від console.log(), метод process.stdout.write() не додає \n наприкінці:
process.stdout.write("Перший рядок");
process.stdout.write("Другий рядок");Результат:
Перший рядокДругий рядокЩоб перейти на новий рядок, додайте символ \n:
process.stdout.write("Перший рядок\n");
process.stdout.write("Другий рядок\n");Створіть файл echo.js:
process.stdin.setEncoding("utf8");
process.stdin.on("data", (chunk) => {
process.stdout.write(`Ви ввели: ${chunk}`);
});Запустіть його:
node echo.jsПісля введення:
Привітпрограма виведе:
Ви ввели: ПривітПодія data може спрацювати кілька разів. Тому програма обробляє кожен отриманий фрагмент окремо.
Іноді потрібно дочекатися, поки користувач або інша програма завершить введення. Для цього можна накопичувати фрагменти в змінній і слухати подію end.
process.stdin.setEncoding("utf8");
let input = "";
process.stdin.on("data", (chunk) => {
input += chunk;
});
process.stdin.on("end", () => {
const text = input.trim();
process.stdout.write(`Увесь текст: ${text}\n`);
});У цьому прикладі:
кожен фрагмент додається до input;
після завершення введення спрацьовує end;
метод trim() видаляє зайві пробіли та перенесення рядків;
увесь текст виводиться через stdout.
Таку програму зручно використовувати з перенаправленням введення:
echo "Node.js читає stdin" | node program.jsОператор | передає результат команди echo у process.stdin програми Node.js.
Наступна програма читає весь текст зі stdin, рахує слова та виводить результат у stdout:
process.stdin.setEncoding("utf8");
let input = "";
process.stdin.on("data", (chunk) => {
input += chunk;
});
process.stdin.on("end", () => {
const text = input.trim();
if (text === "") {
process.stdout.write("Кількість слів: 0\n");
return;
}
const words = text.split(/\s+/);
process.stdout.write(`Кількість слів: ${words.length}\n`);
});Запуск із введенням вручну:
node words.jsАбо передача тексту через іншу команду:
echo "один два три" | node words.jsРезультат:
Кількість слів: 3Регулярний вираз /\s+/ означає один або більше пробільних символів. Завдяки цьому програма правильно обробляє одинарні пробіли, кілька пробілів і перенесення рядків.
Через stdin можна отримувати не лише текст для виведення, а й дані для обчислень.
process.stdin.setEncoding("utf8");
let input = "";
process.stdin.on("data", (chunk) => {
input += chunk;
});
process.stdin.on("end", () => {
const numbers = input
.trim()
.split(/\s+/)
.map(Number);
const sum = numbers.reduce((total, number) => total + number, 0);
process.stdout.write(`Сума: ${sum}\n`);
});Для введення:
10 20 5програма виведе:
Сума: 35Метод map(Number) перетворює рядки на числа, а reduce() обчислює їхню суму.
console.log() і process.stdout.write()Для простого виведення часто використовують console.log():
console.log("Результат:", 42);Але console.log() є зручною функцією вищого рівня, яка форматує значення та додає перенесення рядка.
process.stdout.write() безпосередньо записує рядок у стандартний потік виведення:
process.stdout.write("Результат: 42\n");Використовуйте process.stdout.write(), коли потрібно:
точно контролювати текст виведення;
не додавати перенесення рядка автоматично;
працювати зі стандартним потоком як із потоком даних.
chunk завжди містить один рядокФрагмент може містити частину рядка, кілька рядків або декілька частин даних. Не слід покладатися на те, що одна подія data відповідає одному введеному рядку.
Якщо потрібно обробити весь текст разом, накопичуйте фрагменти та використовуйте подію end.
toString()Без встановленого кодування chunk має тип Buffer:
process.stdin.on("data", (chunk) => {
process.stdout.write(chunk.toString());
});Або заздалегідь встановіть кодування:
process.stdin.setEncoding("utf8");process.stdout.write() не додає перенесення рядка:
process.stdout.write("Готово");Для переходу на новий рядок використовуйте:
process.stdout.write("Готово\n");trim() для порожнього введення без перевіркиПісля trim() введення може стати порожнім рядком. Перед подальшим перетворенням даних перевіряйте його:
const text = input.trim();
if (text === "") {
process.stdout.write("Даних немає\n");
return;
}process.stdin читає дані зі стандартного введення.
process.stdout записує дані у стандартне виведення.
Подія data повідомляє про надходження чергового фрагмента.
Подія end повідомляє про завершення введення.
process.stdin.setEncoding("utf8") перетворює отримані фрагменти на рядки.
process.stdout.write() записує текст без автоматичного перенесення рядка.
Для обробки всього введення потрібно накопичити фрагменти та дочекатися події end.
Дані через stdin можна передавати вручну або за допомогою конвеєра |.