Чому fs.readFile () Node.js повертає буфер замість рядка?


378

Я намагаюся прочитати вміст test.txt(який знаходиться в одній папці джерела Javascript) і відобразити його за допомогою цього коду:

var fs = require("fs");

fs.readFile("test.txt", function (err, data) {
    if (err) throw err;
    console.log(data);
});

Зміст test.txtстворено на nano:

Тестування Node.js readFile ()

І я отримую це:

Nathan-Camposs-MacBook-Pro:node_test Nathan$ node main.js
<Buffer 54 65 73 74 69 6e 67 20 4e 6f 64 65 2e 6a 73 20 72 65 61 64 46 69 6c 65 28 29>
Nathan-Camposs-MacBook-Pro:node_test Nathan$ 

Відповіді:


561

З документів:

Якщо кодування не вказано, то необроблений буфер повертається.

Що може пояснити <Buffer ...>. Вкажіть дійсне кодування, наприклад utf-8, як другий параметр після імені файлу. Як от,

fs.readFile("test.txt", "utf8", function(err, data) {...});

164

спробуйте

fs.readFile("test.txt", "utf8", function(err, data) {...});

в основному вам потрібно вказати кодування.


66

Це виходить високо в Google, тому я хотів би додати деяку контекстуальну інформацію про оригінальне запитання (моє наголос):

Чому fs.readFile () Node.js повертає буфер замість рядка?

Тому що файли не завжди є текстовими

Навіть якщо ти як програміст це знаєте: Node не має уявлення про те, що знаходиться у файлі, який ви намагаєтесь прочитати. Це може бути текстовий файл, але він також може бути архівом ZIP або зображенням JPG - Node не знає.

Тому що читання текстових файлів складне

Навіть якби Node знав, що це читати текстовий файл, він все одно не мав би поняття, яке кодування символів використовується (тобто як байти у файлі відображаються для людей, що читаються символами), тому що сам кодування символів не зберігається у файлі .

Є способи здогадатися кодування символів текстових файлів з більшою або меншою впевненістю (саме це роблять текстові редактори під час відкриття файлу), але зазвичай ви не хочете, щоб ваш код покладався на здогади без вашої чіткої інструкції.

Буфери на допомогу!

Отже, оскільки він не може і не може знати всі ці деталі, Node просто зчитує байт файлу за байтом, не припускаючи нічого про його вміст.

І ось що повертається буфер: ненапружений контейнер для бінарного вмісту. Як слід інтерпретувати цей вміст, залежить від вас як розробника.


10
Це єдина відповідь, яка насправді відповідає на питання в заголовку.
frzsombor

4
@frzsombor З огляду на , що є загальноприйнятий відповідь, я б припустити , ОП дійсно була зацікавлений в отриманні рядків замість буферів і просто не міг фрази правильного питання. Тим не менш, інші люди можуть приїхати сюди з Google, маючи на увазі власне "чому", звідси і моя відповідь. :)
Лойло

44

Асинхронізація:

fs.readFile('test.txt', 'utf8', callback);

Синхронізація:

var content = fs.readFileSync('test.txt', 'utf8');

38

Він повертає об'єкт буфера.

Якщо ви хочете його в рядку, ви можете перетворити його за допомогою data.toString():

var fs = require("fs");

fs.readFile("test.txt", function (err, data) {
    if (err) throw err;
    console.log(data.toString());
});

13
Вигляд старий, але слід знати, що це рішення створює додаткові накладні витрати, оскільки в buffer.toString()будь-якому випадку передбачає кодування utf-8. Таким чином, це було б рівномірно відповіді (хоч і повільніше) @hvgotcodes.
Брендон

14

dataЗмінний містить Bufferоб'єкт. Перетворіть його в кодування ASCII, використовуючи наступний синтаксис:

data.toString('ascii', 0, data.length)

Асинхронно:

fs.readFile('test.txt', 'utf8', function (error, data) {
    if (error) throw error;
    console.log(data.toString());
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.