readFile() 和 readFileSync() 之间的区别

Posted

技术标签:

【中文标题】readFile() 和 readFileSync() 之间的区别【英文标题】:Difference between readFile() and readFileSync() 【发布时间】:2013-07-10 09:40:24 【问题描述】:

以下代码将 index.html 的内容(它只包含文本 hello world)输出到浏览器。但是,当我将readFile() 替换为readFileSync() 时,请求超时。

我错过了什么?是否需要不同类型的缓冲区?我正在使用节点 0.61 并表示 2.4。

var express = require('express');
var fs = require('fs');

var app = express.createServer(express.logger());

app.get('/', function(request, response) 
    fs.readFile('index.html', function(err, data)
        response.send(data.toString());
    );
);

var port = process.env.PORT || 5000;
app.listen(port, function() 
  console.log("Listening on " + port);
);

【问题讨论】:

发送完毕后你不应该打电话给.end()吗?我已经有一段时间没有使用 NodeJS了。 when I replace readFile with readFileSync 是什么意思?第一个需要回调,而另一个不需要。代码应为var data = fs.readFileSync('index.html');。回调永远不会被调用,因为readFileSync 不使用它。这就是超时的来源。假设我理解正确。 @CrazyTrain 他正在使用 Express。它为你做。 @freakish:谢谢。我从来没有使用过 Express。 @freakish 谢谢,你能推荐阅读材料来更好地理解节点和回调吗? 【参考方案1】:

readFileSync() 是同步的,会阻塞执行直到完成。这些将其结果作为返回值返回。 readFile() 是异步的,并在它们在后台运行时立即返回。你传递了一个回调函数,当它们完成时会被调用。 让我们以非阻塞为例。

以下方法以非阻塞方式读取文件

var fs = require('fs');
fs.readFile(filename, "utf8", function(err, data) 
        if (err) throw err;
        console.log(data);
);

以下是以阻塞或同步方式读取文件。

var data = fs.readFileSync(filename);

LOL...如果您不希望 readFileSync() 成为阻塞方式,请采取 参考以下代码。 (原生)

var fs = require('fs');
function readFileAsSync()
    new Promise((resolve, reject)=>
        fs.readFile(filename, "utf8", function(err, data) 
                if (err) throw err;
                resolve(data);
        );
    );


async function callRead()
    let data = await readFileAsSync();
    console.log(data);


callRead();

这意味着幕后 readFileSync() 工作与上述(承诺)基础相同。

【讨论】:

【参考方案2】:
'use strict'
var fs = require("fs");

/***
 * implementation of readFileSync
 */
var data = fs.readFileSync('input.txt');
console.log(data.toString());
console.log("Program Ended");

/***
 * implementation of readFile 
 */
fs.readFile('input.txt', function (err, data) 
    if (err) return console.error(err);
   console.log(data.toString());
);

console.log("Program Ended");

为了更好地理解,运行上面的代码并比较结果..

【讨论】:

【参考方案3】:

fs.readFile 接听电话,如您所展示的那样调用 response.send - 很好。如果您只是将其替换为fs.readFileSync,则需要注意它不会接受回调,因此调用 response.send 的回调将永远不会被调用,因此响应将永远不会结束并且会超时。

如果您不是简单地将 readFile 替换为 readFileSync,则需要显示您的 readFileSync 代码。

另外,请注意,您应该永远在节点 express/webserver 中调用 readFileSync,因为它会在执行 I/O 时占用单线程循环。您希望节点循环处理其他请求,直到 I/O 完成并且您的回调处理代码可以运行。

【讨论】:

可以在服务器启动时调用 readFileSync 从磁盘加载 SSL 证书,因为您需要阻止,直到这些证书准备好。但是,你的大点是完全正确的。 @bryanmac 谢谢,我在哪里可以了解更多关于在 node/express 应用程序中使用或不使用哪些功能? 约定是所有 API 都是异步的,例外使用 xxxSync 格式。避免使用 xxxSync,除非您有意识地想要同步(启动或脚本)。服务器应该是异步的。 另一个资源:blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop

以上是关于readFile() 和 readFileSync() 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

如何将使用 fs.readFileSync() 的 Node.js 代码重构为使用 fs.readFile()?

[Node.js] Read a File in Node.js with fs.readFile and fs.readFileSync

如何为 fs.readFileSync() 捕获没有文件?

从 fs.readFile 获取数据

node 之 fs流读写

node.js的fs核心模块读写文件操作 -----由浅入深