Dlaczego fs.readFile () Node.js zwraca bufor zamiast łańcucha?

377

Próbuję odczytać zawartość test.txt(która znajduje się w tym samym folderze źródła JavaScript) i wyświetlić ją za pomocą tego kodu:

var fs = require("fs");

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

Treść test.txtzostała utworzona na nano:

Testowanie Node.js readFile ()

I dostaję to:

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
źródło

Odpowiedzi:

561

Z dokumentów:

Jeśli nie określono kodowania, zwracany jest bufor surowy.

Co może wyjaśniać <Buffer ...>. Podaj poprawne kodowanie, na przykład utf-8jako drugi parametr po nazwie pliku. Jak na przykład,

fs.readFile("test.txt", "utf8", function(err, data) {...});
David
źródło
164

próbować

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

w zasadzie musisz określić kodowanie.

hvgotcodes
źródło
66

To pojawia się wysoko w Google, dlatego chciałbym dodać informacje kontekstowe na temat pierwotnego pytania (moje wyróżnienie):

Dlaczego fs.readFile () Node.js zwraca bufor zamiast łańcucha?

Ponieważ pliki nie zawsze są tekstem

Nawet jeśli was jako programista wiedzieć to: Węzeł nie ma pojęcia, co jest w pliku, który próbujesz przeczytać. Może to być plik tekstowy, ale równie dobrze może to być archiwum ZIP lub obraz JPG - Node nie wie.

Ponieważ czytanie plików tekstowych jest trudne

Nawet gdyby Node wiedział, że ma odczytać plik tekstowy, nadal nie miałby pojęcia, które kodowanie znaków jest używane (tj. W jaki sposób bajty w pliku mapowane są na znaki czytelne dla człowieka), ponieważ samo kodowanie znaków nie jest przechowywane w pliku .

Istnieją sposoby odgadnięcia kodowania znaków w plikach tekstowych z większą lub mniejszą pewnością (tak właśnie robią edytory tekstu podczas otwierania pliku), ale zwykle nie chcesz, aby Twój kod polegał na domysłach bez wyraźnej instrukcji.

Bufory na ratunek!

Ponieważ więc nie zna i nie może znać wszystkich tych szczegółów, Węzeł po prostu odczytuje bajt pliku bajt, nie zakładając niczego o jego zawartości.

I właśnie taki jest zwrócony bufor: nieopakowany pojemnik na surową zawartość binarną. To, jak należy interpretować tę treść, zależy od Ciebie jako programisty.

Loilo
źródło
10
To jedyna odpowiedź, która faktycznie odpowiada na pytanie zawarte w tytule.
frzsombor
4
@frzsombor Biorąc pod uwagę, że istnieje akceptowana odpowiedź, zakładam, że OP był naprawdę zainteresowany otrzymywaniem łańcuchów zamiast buforów i po prostu nie mógł poprawnie sformułować pytania. Niemniej jednak inni ludzie mogą przyjechać tutaj z Google z myślą o „dlaczego”, stąd moja odpowiedź. :)
Loilo,
44

Asynchronizacja:

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

Synchronizacja:

var content = fs.readFileSync('test.txt', 'utf8');
Taro Alan
źródło
38

Zwraca obiekt buforowy.

Jeśli chcesz w ciągu, możesz przekonwertować go za pomocą data.toString():

var fs = require("fs");

fs.readFile("test.txt", function (err, data) {
    if (err) throw err;
    console.log(data.toString());
});
Andz
źródło
13
Niby stare, ale należy wiedzieć, że to rozwiązanie wprowadza dodatkowy narzut, ponieważ i tak buffer.toString()zakłada kodowanie utf-8. Byłoby to więc równoważne (choć wolniejszej) odpowiedzi @hvgotcodes.
Brandon,
14

dataZmienna zawiera Bufferobiekt. Konwertuj go na kodowanie ASCII przy użyciu następującej składni:

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

Asynchronicznie:

fs.readFile('test.txt', 'utf8', function (error, data) {
    if (error) throw error;
    console.log(data.toString());
});
ayusha
źródło