Por que o fs.readFile () do Node.js retorna um buffer em vez de uma string?

379

Estou tentando ler o conteúdo de test.txt(que está na mesma pasta da fonte Javascript) e exibi-lo usando este código:

var fs = require("fs");

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

O conteúdo do test.txtfoi criado em nano:

Testando Node.js readFile ()

E eu estou entendendo isso:

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$ 
Nathan Campos
fonte

Respostas:

561

Dos documentos:

Se nenhuma codificação for especificada, o buffer bruto será retornado.

O que pode explicar o <Buffer ...>. Especifique uma codificação válida, por exemplo utf-8, como seu segundo parâmetro após o nome do arquivo. Tal como,

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

tentar

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

basicamente você precisa especificar a codificação.

hvgotcodes
fonte
67

Isso aparece no Google, então eu gostaria de adicionar algumas informações contextuais sobre a pergunta original (grifo meu):

Por que o fs.readFile () do Node.js retorna um buffer em vez de uma string?

Como os arquivos nem sempre são textos

Mesmo que você como programador o conheça: o Node não tem idéia do que está no arquivo que você está tentando ler. Pode ser um arquivo de texto, mas também pode ser um arquivo ZIP ou uma imagem JPG - o Node não sabe.

Porque ler arquivos de texto é complicado

Mesmo que o Node soubesse que deveria ler um arquivo de texto, ainda não teria idéia de qual codificação de caracteres é usada (ou seja, como os bytes no arquivo são mapeados para caracteres legíveis por humanos), porque a codificação de caracteres em si não é armazenada no arquivo .

Existem maneiras de adivinhar a codificação de caracteres de arquivos de texto com mais ou menos confiança (é o que os editores de texto fazem ao abrir um arquivo), mas geralmente você não deseja que seu código se baseie em suposições sem instruções explícitas.

Buffers para o resgate!

Portanto, como não conhece e não pode conhecer todos esses detalhes, o Node apenas lê o arquivo byte por byte, sem assumir nada sobre seu conteúdo.

E é isso que o buffer retornado é: um contêiner não-mencionado para conteúdo binário bruto. A decisão de como esse conteúdo deve ser interpretado depende de você, como desenvolvedor.

Loilo
fonte
11
Esta é a única resposta que realmente responde à pergunta no título.
Frzsombor 3/05/19
4
@frzsombor Dado que há uma resposta aceita, eu diria que o OP realmente estava interessado em obter strings em vez de Buffers e simplesmente não conseguia formular a pergunta corretamente. No entanto, outras pessoas podem vir aqui do Google com o "porquê" em mente, daí a minha resposta. :)
Loilo
44

Assíncrono:

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

Sincronizar:

var content = fs.readFileSync('test.txt', 'utf8');
Taro Alan
fonte
38

Ele está retornando um objeto Buffer.

Se você desejar em uma string, poderá convertê-lo com data.toString():

var fs = require("fs");

fs.readFile("test.txt", function (err, data) {
    if (err) throw err;
    console.log(data.toString());
});
Andz
fonte
13
Tipo de idade, mas deve-se saber que esta solução introduz uma sobrecarga extra, pois buffer.toString()assume a codificação utf-8 de qualquer maneira. Portanto, isso seria equivalente à (mais lenta que) resposta do @hvgotcodes.
Brandon
14

A datavariável contém um Bufferobjeto. Converta-o em codificação ASCII usando a seguinte sintaxe:

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

Assíncrona:

fs.readFile('test.txt', 'utf8', function (error, data) {
    if (error) throw error;
    console.log(data.toString());
});
ayusha
fonte