ChatGPT解决这个技术问题 Extra ChatGPT

为什么 Node.js 的 fs.readFile() 返回的是缓冲区而不是字符串?

我正在尝试读取 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$ 

T
Tomáš Zato - Reinstate Monica

来自the docs:

如果未指定编码,则返回原始缓冲区。

这可以解释 <Buffer ...>。指定一个有效的编码,例如 utf-8,作为文件名之后的第二个参数。如,

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

T
Trevor Reid

尝试:

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

基本上,您需要指定编码。


L
Loilo

这在谷歌上很高,所以我想添加一些关于原始问题的上下文信息(强调我的):

为什么 Node.js 的 fs.readFile() 返回的是缓冲区而不是字符串?

因为文件并不总是文本

即使您作为程序员知道:Node 不知道您要读取的文件中的内容。它可以是文本文件,但也可以是 ZIP 存档或 JPG 图像——Node 不知道。

因为阅读文本文件很棘手

即使 Node 知道 它将读取一个文本文件,它仍然不知道使用了哪个 character encoding(即文件中的字节如何映射到人类可读的字符),因为字符编码本身不存储在文件中。

guess 有一些方法可以或多或少地确定文本文件的字符编码(这是文本编辑器在打开文件时所做的),但您通常不希望您的代码在没有明确指示的情况下依赖猜测。

缓冲救援!

所以,因为它不知道也不可能知道所有这些细节,Node 只是逐字节读取文件,而不假设它的内容。

这就是返回的缓冲区:文件中原始字节的无主容器。如何解释这些字节取决于您作为开发人员。


经常缺少 SO 是代码背后的“为什么”。这是非常好的。
@Loilo readFilereadFileSync 是读取文件的所有字节还是只读取表示文件内容的字节
像这样的答案就是为什么我错过了 SO 答案的书签功能。非常感谢这个清晰的解释,@Loilo!
w
wangchi

异步:

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

同步:

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

A
Andz

它正在返回一个 Buffer 对象。

如果您希望它在一个字符串中,您可以使用 data.toString() 进行转换:

var fs = require("fs");

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

有点旧,但应该知道这个解决方案引入了额外的开销,因为 buffer.toString() 无论如何都假定 utf-8 编码。因此,这将等同于(尽管比)@hvgotcodes 的答案。
a
ayusha

data 变量包含一个 Buffer 对象。使用以下语法将其转换为 ASCII 编码:

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

或以 UTF-8 编码:

data = data.toString('utf8', 0, data.length)

异步:

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

S
Shoaib Khalil

您缺少第二个参数的编码方案,通常是 "utf-8"。如果未提及编码方案,则返回纯缓冲区。


c
chinmay prajapat

如果它不是媒体文件,那么您可以使用 .toString() 方法。