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

531

我尝试读取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$ 
8个回答

756

根据文档:

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

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

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

196

尝试:

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

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


144
这在谷歌上很常见,所以我想添加一些关于原始问题的背景信息(强调是我的):
因为文件并不总是文本
即使您作为程序员知道它:Node也不知道您要读取的文件中有什么。它可能是一个文本文件,但也可能是一个ZIP归档文件或JPG图像 - Node不知道。
因为读取文本文件很棘手
即使节点知道它将读取文本文件,它仍然不知道使用哪个字符编码(即文件中的字节如何映射到人类可读的字符),因为字符编码本身没有存储在文件中。
有各种方法可以根据更多或更少的信心猜测文本文件的字符编码(打开文件时文本编辑器所做的就是这样),但通常不希望您的代码依赖于未经明确指示的猜测。
缓冲区来拯救!
因此,由于它不知道所有这些细节,Node只是逐字节读取文件,而不假设其内容。
返回的缓冲区就是这样一个无意见的容器,用于存储文件中的原始字节。如何解释这些字节取决于您作为开发人员的选择。

@Loilo readFilereadFileSync读取的是文件的所有字节还是仅代表文件内容的字节? - Joachim Rives

61

异步:

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

同步:

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

48

它返回一个Buffer对象。

如果你想要一个字符串,你可以使用data.toString()进行转换:

var fs = require("fs");

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

19
有点老了,但需要知道的是,这种解决方案会引入额外的开销,因为buffer.toString()默认假设utf-8编码。因此,这与(虽然比)@hvgotcodes的答案相当,但速度较慢。 - Brandon

22

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());
});

1

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


-1

这只是一个返回内容的函数,要进行编码,需要添加编码参数,如“UTF-8”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接