从 fs.readFile 获取数据

IT技术 javascript node.js
2021-01-23 13:49:25
var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});
console.log(content);

日志undefined,为什么?

6个回答

为了详细说明@Raynos 所说的,您定义的函数是异步回调。它不会立即执行,而是在文件加载完成后执行。当您调用 readFile 时,控制立即返回并执行下一行代码。所以当你调用console.log的时候,你的回调还没有被调用,这个内容还没有被设置。欢迎使用异步编程。

示例方法

const fs = require('fs');
// First I want to read the file
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    const content = data;

    // Invoke the next step here however you like
    console.log(content);   // Put all of the code here (not the best solution)
    processFile(content);   // Or put the next step in a function and invoke it
});

function processFile(content) {
    console.log(content);
}

或者更好的是,如 Raynos 示例所示,将您的调用包装在一个函数中并传入您自己的回调。(显然这是更好的做法)我认为养成将异步调用包装在需要回调的函数中的习惯将为您节省很多麻烦和混乱的代码。

function doSomething (callback) {
    // any async callback invokes callback with response
}

doSomething (function doSomethingAfter(err, result) {
    // process the async result
});
同步 I/O 有它的位置——如果你在做一个小型的构建系统或工具,这很好。在较大的系统或服务器应用程序上,最佳做法是避免它。
2021-03-13 13:49:25
并非一切都是网络服务器。在服务器开始接受请求之前,使用同步版本的方法进行一次性调用并没有什么可怕的。任何使用 Node 的人都应该在使用它之前真正了解原因。绝对在关于它的咆哮博客之前。
2021-03-16 13:49:25
您必须'utf8'在文件名之后包含作为附加参数,否则它只会返回一个缓冲区。请参阅:stackoverflow.com/questions/9168737/...
2021-03-30 13:49:25

实际上有一个同步功能:

http://nodejs.org/api/fs.html#fs_fs_readfilesync_filename_encoding

异步

fs.readFile(filename, [encoding], [callback])

异步读取文件的全部内容。例子:

fs.readFile('/etc/passwd', function (err, data) {
  if (err) throw err;
  console.log(data);
});

回调传递了两个参数 (err, data),其中 data 是文件的内容。

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


同步

fs.readFileSync(filename, [encoding])

fs.readFile 的同步版本。返回名为 filename 的文件的内容。

如果指定了编码,则此函数返回一个字符串。否则它返回一个缓冲区。

var text = fs.readFileSync('test.md','utf8')
console.log (text)
快速提问,在 readFile 的同步版本中返回的缓冲区有什么用?如果我同步读取文件并且不传递任何编码,它会打印缓冲区,我该如何使用它?谢谢你。
2021-03-24 13:49:25
此外,据我所知,缓冲区是八位字节流,非常适合“一块一块地”发送数据。您一定已经看到缓冲区类似于AF 42 F1. 对于客户端-服务器-客户端通信非常实用。
2021-04-08 13:49:25
我最近有这方面的经验。假设我们的缓冲区是data. if (Buffer.isBuffer( data){ result = data.toString('utf8'); }现在我们已将缓冲区转换为可读文本。这适用于读取纯文本文件或针对格式类型测试文件。例如,我可以执行 try/catch 以查看它是否是 JSON 文件;但只有在缓冲区转换为文本之后。在这里查看更多信息:nodejs.org/api/buffer.html
2021-04-09 13:49:25
function readContent(callback) {
    fs.readFile("./Index.html", function (err, content) {
        if (err) return callback(err)
        callback(null, content)
    })
}

readContent(function (err, content) {
    console.log(content)
})
你好,在你的代码的第一行中function readContent(callback),, 是callback保留字吗?我的意思是,这是为您的自定义函数实现回调的标准方法吗?我刚开始学习节点。
2021-03-14 13:49:25
readContent(function (err, content) 使用该函数作为参数时给我一个语法错误。
2021-03-19 13:49:25
嗨,阿马尔。回调只是传递给他的函数的参数,它可以是eventc任何你喜欢的名字——它不是 Javascript 中的保留字,我认为同样的扩展到 Node.js。
2021-04-02 13:49:25

在 ES7 中使用 Promise

与 mz/fs 异步使用

mzmodule提供了核心节点库的promisified 版本。使用它们很简单。首先安装库...

npm install mz

然后...

const fs = require('mz/fs');
fs.readFile('./Index.html').then(contents => console.log(contents))
  .catch(err => console.error(err));

或者,您可以在异步函数中编写它们:

async function myReadfile () {
  try {
    const file = await fs.readFile('./Index.html');
  }
  catch (err) { console.error( err ) }
};
看起来很有趣。一个错字:'console.error(catch)' 应该是 'console.error(err)' 我猜)。
2021-04-05 13:49:25
如果您不想添加额外的包,请尝试以下@doctorlee 的解决方案
2021-04-09 13:49:25
var data = fs.readFileSync('tmp/reltioconfig.json','utf8');

使用它来同步调用文件,而不将其显示输出编码为缓冲区。

您需要在代码块之前添加一个空行,以便进行漂亮的打印。
2021-03-22 13:49:25