¿Por qué el fs.readFile () de Node.js devuelve un búfer en lugar de una cadena?

380

Estoy tratando de leer el contenido de test.txt(que está en la misma carpeta de la fuente Javascript) y mostrarlo usando este código:

var fs = require("fs");

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

El contenido del test.txtfue creado en nano:

Prueba de Node.js readFile ()

Y estoy obteniendo esto:

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
fuente

Respuestas:

562

De los documentos:

Si no se especifica codificación, se devuelve el búfer sin procesar.

Lo que podría explicar el <Buffer ...>. Especifique una codificación válida, por ejemplo utf-8, como su segundo parámetro después del nombre del archivo. Como,

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

tratar

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

básicamente necesitas especificar la codificación.

hvgotcodes
fuente
68

Esto aparece en Google, por lo que me gustaría agregar información contextual sobre la pregunta original (énfasis mío):

¿ Por qué el fs.readFile () de Node.js devuelve un búfer en lugar de una cadena?

Porque los archivos no siempre son texto

Incluso si usted como programador lo sabe: Node no tiene idea de qué hay en el archivo que está intentando leer. Podría ser un archivo de texto, pero también podría ser un archivo ZIP o una imagen JPG. Node no lo sabe.

Porque leer archivos de texto es complicado

Incluso si Node supiera que es para leer un archivo de texto, aún no tendría idea de qué codificación de caracteres se utiliza (es decir, cómo los bytes en el archivo se asignan a caracteres legibles por humanos), porque la codificación de caracteres en sí no se almacena en el archivo .

Hay formas de adivinar la codificación de caracteres de los archivos de texto con más o menos confianza (eso es lo que hacen los editores de texto al abrir un archivo), pero generalmente no desea que su código se base en conjeturas sin su instrucción explícita.

¡Amortiguadores al rescate!

Entonces, debido a que no conoce ni puede conocer todos estos detalles, Node solo lee el archivo byte por byte, sin asumir nada sobre su contenido.

Y eso es lo que es el búfer devuelto: un contenedor no opinado para contenido binario sin procesar. Cómo debe interpretarse este contenido depende de usted como desarrollador.

Loilo
fuente
12
Esta es la única respuesta que realmente responde la pregunta en el título.
frzsombor
44
@frzsombor Dado que hay una respuesta aceptada, asumiría que el OP realmente estaba interesado en obtener cadenas en lugar de Buffers y simplemente no podía formular la pregunta correctamente. Sin embargo, otras personas pueden venir de Google con el "por qué" real en mente, de ahí mi respuesta. :)
Loilo
44

Asíncrono:

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

Sincronización:

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

Está devolviendo un objeto Buffer.

Si lo quieres en una cadena, puedes convertirlo con data.toString():

var fs = require("fs");

fs.readFile("test.txt", function (err, data) {
    if (err) throw err;
    console.log(data.toString());
});
Andz
fuente
13
Algo antiguo, pero se debe saber que esta solución introduce una sobrecarga adicional ya que buffer.toString()supone la codificación utf-8 de todos modos. Por lo tanto, esto sería equivalente a (aunque más lento que) la respuesta de @hvgotcodes.
Brandon
14

La datavariable contiene un Bufferobjeto. Conviértalo en codificación ASCII utilizando la siguiente sintaxis:

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

Asincrónicamente:

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