node.js 中关于 fs 的问题
Questions regarding fs in node.js
Objective
要知道 fs.writeFileSync()
或 fs.writeFile()
何时完成写入文件,以便我可以执行另一个函数。
背景
我正在使用 fs
编写文件,为了知道文件何时完成编写,我查看了它的文档:
看完后,我把注意力集中在了fs.writeFile()
和fs.writeFileSync()
两个地方,但发现缺少文档,我有疑问。
关于fs.writeFile()
的问题
- 回调函数是在文件写入前调用,写入时调用还是写入保存到磁盘后调用?
关于fs.writeFileSync()
的问题
- 如果总是 returns
undefined
,我怎么知道是否发生了错误?
- 同步写入是否意味着我的代码将被迫等待文件完全写入?
一般问题
- 如果我想同时写入两个不同的文件,并在两个文件都完成后执行一个操作,我将如何使用
fs.writeFile()
来实现?
- NPM 中是否有任何用户友好的库来完成此类工作?我搜索过,但没有找到任何令人信服的东西。
结论
我总体上对 fs
感到困惑,而且我的知识不足以在我的代码中最大限度地使用它。为了改进,我需要看到更多的代码示例,所以有代码示例的答案将是首选。
感谢您的宝贵时间!
这么多问题...让我们开始吧:
(fs.writeFile()
...) 回调函数是在写入文件前调用,写入时调用还是写入存盘后调用?
操作完成后,是否成功。
(fs.writeFileSync()
...) 如果总是 returns undefined
我如何知道是否发生错误?
它will throw an exception.
作为同步写入,是否意味着我的代码将被强制等待直到文件完全写入?
是的!这就是同步函数的意义所在。
如果我想同时写入两个不同的文件,并在两个都完成后执行一个动作,我该如何使用fs.writeFile()
?
这是一种方法:
const fs = require('fs');
let completions = 0;
function onComplete(err) {
if(err) {
console.log('An error occurred', err);
}
completions++;
if(completions === 2) {
console.log('All done!');
}
}
fs.writeFile('file1.txt', 'Hello', onComplete);
fs.writeFile('file2.txt', 'World', onComplete);
NPM 中是否有任何用户友好的库来完成此类工作?我搜索过,但没有找到任何令人信服的东西。
不完全是(据我所知...),但是您应该 考虑使用 promises 和 promisified fs
电话。然后你就可以使用Promise.all
,一切都会好看多了!
首先,这是一个重要提示。如果文档没有解释某些内容并且您不能通过简单的测试轻松回答问题,那么您可以随时查看 GitHub 上的源代码。例如,这里是 the source for fs.writeFileSync() on Github。这是开源项目的巨大优势之一。有疑问就去看代码吧
有时,找到正确的源代码并不那么容易(GitHub 搜索往往会发现测试用例代码中的命中率是原始源代码中的 10 倍)。在这些情况下,您可以在调试器中自己的代码中设置一个断点,然后直接进入有问题的函数。调试器会将您带到源代码,您可以准确地看到它在做什么。
现在回答您的问题...
Questions about fs.writeFile()
Is the callback function called before the file is written, as it is
being written or after it was written and saved in disk?
写入文件后调用(或遇到错误时)。
Questions about fs.writeFileSync()
- How do I know if an error occurred if it always returns undefined?
fs.writeFileSync 如果有错误则抛出异常。您必须使用 try/catch 来捕获任何异常。
- Being a synchronous write, does it mean that my code will be forced to
wait until the file is fully written ?
是的,同步版本会阻塞,直到文件完全写入。您不会在正常的服务器开发中使用同步版本,因为它会占用主 node.js 线程。
General questions
If I wanted to write two different files at the same time, and to
perform a single action when both are complete, how would I do it
using fs.writeFile()?
目前此类问题的典型设计模式是使用 promises 和 Promise.all()
来跟踪多个异步操作的完成情况。
使用 Bluebird promise 库:
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));
Promise.all([fs.writeFileAsync(fname1, data1), fs.writeFileAsync(fname2, data2)]).then(function() {
// both async operations are done here
}).catch(function(err) {
// handle error here
});
Bluebird 的 .promisifyAll()
方法将 fs 模块中的每个异步操作包装在一个函数中,该函数返回一个承诺,并用 Async
后缀命名包装版本,因此 fs.writeFile()
得到 fs.writeFileAsync()
returns 承诺而不是直接回调。然后,您可以使用 Promise.all()
等 Promise 控制流来管理或协调多个异步操作。
您不必为此使用 Bluebird 库,因为 Promises 现在已内置到 node.js 中(并且是 ES6 规范的一部分),但是 node.js 没有那么简单将现有异步回调函数转换为 promise 返回函数的方法,Bluebird 做到了。如果你愿意,你可以自己做 promisification。
const fs = require('fs');
fs.writeFileAsync = function(fname, data) {
return new Promise(function(resolve, reject) {
fs.writeFile(fname, data, function(err) {
if (err) return reject(err);
resolve();
});
});
}
Promise.all([fs.writeFileAsync(fname1, data1), fs.writeFileAsync(fname2, data2)]).then(function() {
// both async operations are done here
}).catch(function(err) {
// handle error here
});
fs.writeFile() 是异步的。这意味着回调发生在文件被写入之后。 fs.writeFileSync() 不是,这意味着它是非阻塞的,将执行其他后续代码。要写入两个单独的文件,
并在它们都完成后做一些事情,您只需嵌套 aysnc 回调,例如
fs.writeFile('test.txt', 'text', function(){
fs.writeFile('test2.txt', 'text', function(){
console.log('done');
});
});
要知道同步函数有错误,你会使用异常。
Is the fs.writeFile()
callback function called before the file is written, as it is being written or after it was written and saved in disk?
当文件完成写入磁盘时调用该函数。
How do I know if an error occurred in fs.writeFileSync()
if it always returns undefined
?
> fs.writeFileSync('/test', 'foo')
Error: EACCES: permission denied, open '/test'
at Error (native)
...
它会 throw
一个你可以 try..catch
的错误。
fs.writeFileSync()
being a synchronous write, does it mean that my code will be forced to wait until the file is fully written ?
是;与所有同步函数一样,您的代码将阻塞直到函数 returns.
If I wanted to write two different files at the same time, and to perform a single action when both are complete, how would I do it using fs.writeFile()
?
使用promises:
let write1 = new Promise((resolve, reject) => {
fs.writeFile(file1, data1, err => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
let write2 = new Promise(/* same thing here */);
Promise.all([write1, write2]).then(() => {
console.log('both writes done');
});
这是您要查找的内容:
Q1)回调函数是在文件写入前、写入时调用还是写入存盘后调用?
Ans1) 回调函数returns 尝试写入文件操作后的错误或成功。尝试失败或成功写入。所以会return错误,回调成功。所以最后,回调在 "write file operation is attempted".
之后被调用
Q2)如果总是return未定义,我怎么知道是否发生了错误?
Ans2) 您可以使用 try 和 catch,因为如果写入成功,则 return 没有响应,但如果写入失败。你会得到一个例外。
Q3)作为同步写入,是否意味着我的代码将被强制等待直到文件完全写入?
Ans3)是的,本质上是同步的,在写入整个文件写入任务之前不要让其他 statements/operation 执行。
Q4)如果我想同时写入两个不同的文件,并在两个文件都完成后执行一个动作,我该如何使用fs.writeFile()来完成?
Ans4) 因此,在这种情况下,您可以使用回调或承诺。简单来说,您可以将任务一个接一个地链接起来 如果它们相互依赖 。但是如果相互独立就简单的写两块代码。它会很容易写。下面给出的代码用于两个独立的任务。
fs.writeFile('file.txt', 'hello', function(error){ //do something }); fs.writeFile('file1.txt', 'Amulya', function(error){ //do something});
它们会同时执行,因为异步性质,它们会毫不费力地完成。
Q5) NPM 中是否有任何用户友好的库可以完成此类工作?我搜索过,但没有找到任何令人信服的东西。
Ans5) 如果两个任务如上例所示相互独立,则确实不需要 NPM 库。如果它们相互依赖,那么您可以使用 async
或 bluebird
来 链接或承诺 它们。
Objective
要知道 fs.writeFileSync()
或 fs.writeFile()
何时完成写入文件,以便我可以执行另一个函数。
背景
我正在使用 fs
编写文件,为了知道文件何时完成编写,我查看了它的文档:
看完后,我把注意力集中在了fs.writeFile()
和fs.writeFileSync()
两个地方,但发现缺少文档,我有疑问。
关于fs.writeFile()
的问题
- 回调函数是在文件写入前调用,写入时调用还是写入保存到磁盘后调用?
关于fs.writeFileSync()
的问题
- 如果总是 returns
undefined
,我怎么知道是否发生了错误? - 同步写入是否意味着我的代码将被迫等待文件完全写入?
一般问题
- 如果我想同时写入两个不同的文件,并在两个文件都完成后执行一个操作,我将如何使用
fs.writeFile()
来实现? - NPM 中是否有任何用户友好的库来完成此类工作?我搜索过,但没有找到任何令人信服的东西。
结论
我总体上对 fs
感到困惑,而且我的知识不足以在我的代码中最大限度地使用它。为了改进,我需要看到更多的代码示例,所以有代码示例的答案将是首选。
感谢您的宝贵时间!
这么多问题...让我们开始吧:
(fs.writeFile()
...) 回调函数是在写入文件前调用,写入时调用还是写入存盘后调用?
操作完成后,是否成功。
(fs.writeFileSync()
...) 如果总是 returns undefined
我如何知道是否发生错误?
它will throw an exception.
作为同步写入,是否意味着我的代码将被强制等待直到文件完全写入?
是的!这就是同步函数的意义所在。
如果我想同时写入两个不同的文件,并在两个都完成后执行一个动作,我该如何使用fs.writeFile()
?
这是一种方法:
const fs = require('fs');
let completions = 0;
function onComplete(err) {
if(err) {
console.log('An error occurred', err);
}
completions++;
if(completions === 2) {
console.log('All done!');
}
}
fs.writeFile('file1.txt', 'Hello', onComplete);
fs.writeFile('file2.txt', 'World', onComplete);
NPM 中是否有任何用户友好的库来完成此类工作?我搜索过,但没有找到任何令人信服的东西。
不完全是(据我所知...),但是您应该 考虑使用 promises 和 promisified fs
电话。然后你就可以使用Promise.all
,一切都会好看多了!
首先,这是一个重要提示。如果文档没有解释某些内容并且您不能通过简单的测试轻松回答问题,那么您可以随时查看 GitHub 上的源代码。例如,这里是 the source for fs.writeFileSync() on Github。这是开源项目的巨大优势之一。有疑问就去看代码吧
有时,找到正确的源代码并不那么容易(GitHub 搜索往往会发现测试用例代码中的命中率是原始源代码中的 10 倍)。在这些情况下,您可以在调试器中自己的代码中设置一个断点,然后直接进入有问题的函数。调试器会将您带到源代码,您可以准确地看到它在做什么。
现在回答您的问题...
Questions about fs.writeFile()
Is the callback function called before the file is written, as it is being written or after it was written and saved in disk?
写入文件后调用(或遇到错误时)。
Questions about fs.writeFileSync()
- How do I know if an error occurred if it always returns undefined?
fs.writeFileSync 如果有错误则抛出异常。您必须使用 try/catch 来捕获任何异常。
- Being a synchronous write, does it mean that my code will be forced to wait until the file is fully written ?
是的,同步版本会阻塞,直到文件完全写入。您不会在正常的服务器开发中使用同步版本,因为它会占用主 node.js 线程。
General questions
If I wanted to write two different files at the same time, and to perform a single action when both are complete, how would I do it using fs.writeFile()?
目前此类问题的典型设计模式是使用 promises 和 Promise.all()
来跟踪多个异步操作的完成情况。
使用 Bluebird promise 库:
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));
Promise.all([fs.writeFileAsync(fname1, data1), fs.writeFileAsync(fname2, data2)]).then(function() {
// both async operations are done here
}).catch(function(err) {
// handle error here
});
Bluebird 的 .promisifyAll()
方法将 fs 模块中的每个异步操作包装在一个函数中,该函数返回一个承诺,并用 Async
后缀命名包装版本,因此 fs.writeFile()
得到 fs.writeFileAsync()
returns 承诺而不是直接回调。然后,您可以使用 Promise.all()
等 Promise 控制流来管理或协调多个异步操作。
您不必为此使用 Bluebird 库,因为 Promises 现在已内置到 node.js 中(并且是 ES6 规范的一部分),但是 node.js 没有那么简单将现有异步回调函数转换为 promise 返回函数的方法,Bluebird 做到了。如果你愿意,你可以自己做 promisification。
const fs = require('fs');
fs.writeFileAsync = function(fname, data) {
return new Promise(function(resolve, reject) {
fs.writeFile(fname, data, function(err) {
if (err) return reject(err);
resolve();
});
});
}
Promise.all([fs.writeFileAsync(fname1, data1), fs.writeFileAsync(fname2, data2)]).then(function() {
// both async operations are done here
}).catch(function(err) {
// handle error here
});
fs.writeFile() 是异步的。这意味着回调发生在文件被写入之后。 fs.writeFileSync() 不是,这意味着它是非阻塞的,将执行其他后续代码。要写入两个单独的文件, 并在它们都完成后做一些事情,您只需嵌套 aysnc 回调,例如
fs.writeFile('test.txt', 'text', function(){
fs.writeFile('test2.txt', 'text', function(){
console.log('done');
});
});
要知道同步函数有错误,你会使用异常。
Is the
fs.writeFile()
callback function called before the file is written, as it is being written or after it was written and saved in disk?
当文件完成写入磁盘时调用该函数。
How do I know if an error occurred in
fs.writeFileSync()
if it always returnsundefined
?
> fs.writeFileSync('/test', 'foo')
Error: EACCES: permission denied, open '/test'
at Error (native)
...
它会 throw
一个你可以 try..catch
的错误。
fs.writeFileSync()
being a synchronous write, does it mean that my code will be forced to wait until the file is fully written ?
是;与所有同步函数一样,您的代码将阻塞直到函数 returns.
If I wanted to write two different files at the same time, and to perform a single action when both are complete, how would I do it using
fs.writeFile()
?
使用promises:
let write1 = new Promise((resolve, reject) => {
fs.writeFile(file1, data1, err => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
let write2 = new Promise(/* same thing here */);
Promise.all([write1, write2]).then(() => {
console.log('both writes done');
});
这是您要查找的内容:
Q1)回调函数是在文件写入前、写入时调用还是写入存盘后调用?
Ans1) 回调函数returns 尝试写入文件操作后的错误或成功。尝试失败或成功写入。所以会return错误,回调成功。所以最后,回调在 "write file operation is attempted".
之后被调用Q2)如果总是return未定义,我怎么知道是否发生了错误?
Ans2) 您可以使用 try 和 catch,因为如果写入成功,则 return 没有响应,但如果写入失败。你会得到一个例外。
Q3)作为同步写入,是否意味着我的代码将被强制等待直到文件完全写入?
Ans3)是的,本质上是同步的,在写入整个文件写入任务之前不要让其他 statements/operation 执行。
Q4)如果我想同时写入两个不同的文件,并在两个文件都完成后执行一个动作,我该如何使用fs.writeFile()来完成?
Ans4) 因此,在这种情况下,您可以使用回调或承诺。简单来说,您可以将任务一个接一个地链接起来 如果它们相互依赖 。但是如果相互独立就简单的写两块代码。它会很容易写。下面给出的代码用于两个独立的任务。
fs.writeFile('file.txt', 'hello', function(error){ //do something }); fs.writeFile('file1.txt', 'Amulya', function(error){ //do something});
它们会同时执行,因为异步性质,它们会毫不费力地完成。
Q5) NPM 中是否有任何用户友好的库可以完成此类工作?我搜索过,但没有找到任何令人信服的东西。
Ans5) 如果两个任务如上例所示相互独立,则确实不需要 NPM 库。如果它们相互依赖,那么您可以使用 async
或 bluebird
来 链接或承诺 它们。