Pourquoi fs.readFile () de Node.js renvoie-t-il un tampon au lieu d'une chaîne?


380

J'essaie de lire le contenu de test.txt(qui se trouve dans le même dossier que la source Javascript) et de l'afficher en utilisant ce code:

var fs = require("fs");

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

Le contenu du test.txt été créé le nano:

Test de Node.js readFile ()

Et je reçois ceci:

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$ 

Réponses:


562

De la documentation:

Si aucun codage n'est spécifié, le tampon brut est renvoyé.

Ce qui pourrait expliquer le <Buffer ...>. Spécifiez un codage valide, par exemple utf-8, comme deuxième paramètre après le nom de fichier. Tel que,

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

165

essayer

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

fondamentalement, vous devez spécifier l'encodage.


68

Cela revient haut sur Google, donc je voudrais ajouter quelques informations contextuelles sur la question d'origine (c'est moi qui souligne):

Pourquoi fs.readFile () de Node.js renvoie-t-il un tampon au lieu d'une chaîne?

Parce que les fichiers ne sont pas toujours du texte

Même si vous en tant que programmeur le savez: Node n'a aucune idée du contenu du fichier que vous essayez de lire. Il peut s'agir d'un fichier texte, mais il peut tout aussi bien s'agir d'une archive ZIP ou d'une image JPG - Node ne sait pas.

Parce que la lecture des fichiers texte est délicate

Même si Node savait qu'il devait lire un fichier texte, il n'aurait toujours aucune idée du codage des caractères utilisé (c'est-à-dire comment les octets dans le fichier sont mappés en caractères lisibles par l'homme), car le codage de caractères lui-même n'est pas stocké dans le fichier .

Il y a moyen de deviner l'encodage des caractères des fichiers texte avec plus ou moins de confiance (c'est ce que font les éditeurs de texte lors de l'ouverture d'un fichier), mais vous ne voulez généralement pas que votre code repose sur des suppositions sans votre instruction explicite.

Des tampons à la rescousse!

Donc, parce qu'il ne connaît pas et ne peut pas connaître tous ces détails, Node lit simplement le fichier octet par octet, sans rien supposer de son contenu.

Et c'est ce que le tampon retourné est: un conteneur sans opinion pour le contenu binaire brut. La façon dont ce contenu doit être interprété dépend de vous en tant que développeur.


12
C'est la seule réponse qui répond réellement à la question dans le titre.
frzsombor

4
@frzsombor Étant donné qu'il existe une réponse acceptée, je suppose que l'OP était vraiment intéressé à obtenir des chaînes au lieu de tampons et ne pouvait tout simplement pas formuler la question correctement. Néanmoins, d'autres personnes pourraient venir de Google avec le «pourquoi» en tête, d'où ma réponse. :)
Loilo

44

Async:

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

Sync:

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

38

Il renvoie un objet Buffer.

Si vous le voulez dans une chaîne, vous pouvez le convertir avec data.toString():

var fs = require("fs");

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

13
Un peu vieux, mais il faut savoir que cette solution introduit une surcharge supplémentaire puisqu'elle buffer.toString()suppose de toute façon le codage utf-8. Ainsi, cela équivaudrait à (bien que plus lentement que) la réponse de @hvgotcodes.
Brandon

14

La datavariable contient un Bufferobjet. Convertissez-le en encodage ASCII en utilisant la syntaxe suivante:

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

De manière asynchrone:

fs.readFile('test.txt', 'utf8', function (error, data) {
    if (error) throw error;
    console.log(data.toString());
});
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.