Почему Node.js 'fs.readFile () возвращает буфер вместо строки?


380

Я пытаюсь прочитать содержимое 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$ 

Ответы:


562

Из документов:

Если кодировка не указана, возвращается необработанный буфер.

Который мог бы объяснить <Buffer ...>. Укажите правильную кодировку, например utf-8, в качестве второго параметра после имени файла. Такие как,

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

165

пытаться

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

в основном вам нужно указать кодировку.


68

Это высоко ценится в Google, поэтому я хотел бы добавить некоторую контекстную информацию об исходном вопросе (выделение мое):

Почему Node.js 'fs.readFile () возвращает буфер вместо строки?

Потому что файлы не всегда текстовые

Даже если вы, как программист, знаете это: Node не знает, что находится в файле, который вы пытаетесь прочитать. Это может быть текстовый файл, но это также может быть ZIP-архив или изображение в формате JPG - Node не знает.

Потому что читать текстовые файлы сложно

Даже если бы Node знал, что нужно читать текстовый файл, он все равно не знал бы, кодировка символов используется (т. Е. Как байты в файле отображаются на читаемые человеком символы), поскольку сама кодировка символов не сохраняется в файле. ,

Есть способы угадать кодировку символов текстовых файлов с большей или меньшей достоверностью (это то, что текстовые редакторы делают при открытии файла), но вы обычно не хотите, чтобы ваш код полагался на догадки без вашего явного указания.

Буферы на помощь!

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

И это то, что является возвращаемым буфером: нерафинированный контейнер для необработанного двоичного содержимого. Как этот контент следует интерпретировать, решать вам как разработчику.


12
Это единственный ответ, который фактически отвечает на вопрос в заголовке.
frzsombor

4
@frzsombor Учитывая , что есть общепринятый ответ, я бы предположить , ОП действительно была заинтересован в получении строк вместо буферов и просто не мог фразы правильного вопроса. Тем не менее, другие люди могут прийти сюда из Google с фактическим «почему», поэтому мой ответ. :)
Loilo

45

асинхронный:

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

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

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

38

Он возвращает объект Buffer.

Если вы хотите, чтобы это было в строке, вы можете преобразовать его с помощью 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.