node.js 如果父文件夹不存在,如何写入文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16316330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to write file if parent folder doesn't exist?
提问by Erik
I need to write file to the following path:
我需要将文件写入以下路径:
fs.writeFile('/folder1/folder2/file.txt', 'content', function () {…});
But '/folder1/folder2'path may not exists. So I get the following error:
但'/folder1/folder2'路径可能不存在。所以我收到以下错误:
message=ENOENT, open /folder1/folder2/file.txt
消息=ENOENT,打开/folder1/folder2/file.txt
How can I write content to that path?
如何将内容写入该路径?
回答by Myrne Stol
Use mkdirpin combination with path.dirnamefirst.
使用mkdirp与结合path.dirname第一。
var mkdirp = require('mkdirp');
var fs = require('fs');
var getDirName = require('path').dirname;
function writeFile(path, contents, cb) {
mkdirp(getDirName(path), function (err) {
if (err) return cb(err);
fs.writeFile(path, contents, cb);
});
}
If the whole path already exists, mkdirpis a noop. Otherwise it creates all missing directories for you.
如果整个路径已经存在,mkdirp则为 noop。否则,它会为您创建所有丢失的目录。
This module does what you want: https://npmjs.org/package/writefile. Got it when googling for "writefile mkdirp". This module returns a promise instead of taking a callback, so be sure to read some introduction to promises first. It might actually complicate things for you.
这个模块做你想做的:https://npmjs.org/package/writefile。在谷歌搜索“writefile mkdirp”时得到了它。这个模块返回一个promise而不是一个回调,所以一定要先阅读一些promise的介绍。它实际上可能会让你的事情复杂化。
The function I gave works in any case.
我给出的函数在任何情况下都有效。
回答by tkarls
I find that the easiest way to do this is to use the outputFile() method from the fs-extramodule.
我发现最简单的方法是使用fs-extra模块中的outputFile() 方法。
Almost the same as writeFile (i.e. it overwrites), except that if the parent directory does not exist, it's created. options are what you'd pass to fs.writeFile().
几乎与 writeFile 相同(即覆盖),除了如果父目录不存在,则创建它。options 是您传递给 fs.writeFile() 的内容。
Example:
例子:
var fs = require('fs-extra');
var file = '/tmp/this/path/does/not/exist/file.txt'
fs.outputFile(file, 'hello!', function (err) {
console.log(err); // => null
fs.readFile(file, 'utf8', function (err, data) {
console.log(data); // => hello!
});
});
It also has promise support out of the box these days!.
这些天它还具有开箱即用的承诺支持!
回答by kevincoleman
Perhaps most simply, you can just use the fs-pathnpm module.
也许最简单的是,您可以只使用fs-pathnpm 模块。
Your code would then look like:
您的代码将如下所示:
var fsPath = require('fs-path');
fsPath.writeFile('/folder1/folder2/file.txt', 'content', function(err){
if(err) {
throw err;
} else {
console.log('wrote a file like DaVinci drew machines');
}
});
回答by Mouneer
Edit
编辑
NodeJS version 10 has added a native support for both mkdirand mkdirSyncto create the parent director recursively with recursive: trueoption as the following:
NodeJS 版本 10 添加了对两者的原生支持,mkdir并mkdirSync使用recursive: true如下选项递归创建父主管:
fs.mkdirSync(targetDir, { recursive: true });
And if you prefer fs Promises API, you can write
如果你愿意fs Promises API,你可以写
fs.promises.mkdir(targetDir, { recursive: true });
Original Answer
原答案
Create the parent directories recursively if they do not exist! (Zero dependencies)
如果父目录不存在,则递归创建它们!(零依赖)
const fs = require('fs');
const path = require('path');
function mkDirByPathSync(targetDir, { isRelativeToScript = false } = {}) {
const sep = path.sep;
const initDir = path.isAbsolute(targetDir) ? sep : '';
const baseDir = isRelativeToScript ? __dirname : '.';
return targetDir.split(sep).reduce((parentDir, childDir) => {
const curDir = path.resolve(baseDir, parentDir, childDir);
try {
fs.mkdirSync(curDir);
} catch (err) {
if (err.code === 'EEXIST') { // curDir already exists!
return curDir;
}
// To avoid `EISDIR` error on Mac and `EACCES`-->`ENOENT` and `EPERM` on Windows.
if (err.code === 'ENOENT') { // Throw the original parentDir error on curDir `ENOENT` failure.
throw new Error(`EACCES: permission denied, mkdir '${parentDir}'`);
}
const caughtErr = ['EACCES', 'EPERM', 'EISDIR'].indexOf(err.code) > -1;
if (!caughtErr || caughtErr && curDir === path.resolve(targetDir)) {
throw err; // Throw if it's just the last created dir.
}
}
return curDir;
}, initDir);
}
Usage
用法
// Default, make directories relative to current working directory.
mkDirByPathSync('path/to/dir');
// Make directories relative to the current script.
mkDirByPathSync('path/to/dir', {isRelativeToScript: true});
// Make directories with an absolute path.
mkDirByPathSync('/path/to/dir');
Demo
演示
Explanations
说明
- [UPDATE]This solution handles platform-specific errors like
EISDIRfor Mac andEPERMandEACCESfor Windows. - This solution handles both relativeand absolutepaths.
- In the case of relative paths, target directories will be created (resolved) in the current working directory. To Resolve them relative to the current script dir, pass
{isRelativeToScript: true}. - Using
path.sepandpath.resolve(), not just/concatenation, to avoid cross-platform issues. - Using
fs.mkdirSyncand handling the error withtry/catchif thrown to handle race conditions: another process may add the file between the calls tofs.existsSync()andfs.mkdirSync()and causes an exception.- The other way to achieve that could be checking if a file exists then creating it, I.e,
if (!fs.existsSync(curDir) fs.mkdirSync(curDir);. But this is an anti-pattern that leaves the code vulnerable to race conditions.
- The other way to achieve that could be checking if a file exists then creating it, I.e,
- Requires Node v6and newer to support destructuring. (If you have problems implementing this solution with old Node versions, just leave me a comment)
- [更新]该解决方案把手平台特有的错误,如
EISDIRMac和EPERM和EACCES用于Windows。 - 此解决方案处理相对路径和绝对路径。
- 在相对路径的情况下,将在当前工作目录中创建(解析)目标目录。要相对于当前脚本目录解析它们,请传递
{isRelativeToScript: true}. - 使用
path.sepandpath.resolve(),而不仅仅是/串联,以避免跨平台问题。 - 使用
fs.mkdirSync和处理错误try/catchif 来处理竞争条件:另一个进程可能会在对fs.existsSync()和的调用之间添加文件fs.mkdirSync()并导致异常。- 实现这一目标的另一种方法是检查文件是否存在,然后创建它,即
if (!fs.existsSync(curDir) fs.mkdirSync(curDir);. 但这是一种反模式,使代码容易受到竞争条件的影响。
- 实现这一目标的另一种方法是检查文件是否存在,然后创建它,即
- 需要Node v6和更新版本来支持解构。(如果您在使用旧 Node 版本实施此解决方案时遇到问题,请给我留言)
回答by MikeD
You can use
您可以使用
fs.stat('/folder1/folder2', function(err, stats){ ... });
statsis a fs.Statstype of object, you may check stats.isDirectory(). Depending on the examination of errand statsyou can do something, fs.mkdir( ... )or throw an error.
stats是一种fs.Stats对象,您可以检查stats.isDirectory(). 根据检查结果err,stats你可以做些什么,fs.mkdir( ... )或者抛出一个错误。
Update: Fixed the commas in the code.
更新:修复了代码中的逗号。
回答by math_lab3.ca
Here's my custom function to recursively create directories (with no external dependencies):
这是我递归创建目录的自定义函数(没有外部依赖项):
var fs = require('fs');
var path = require('path');
var myMkdirSync = function(dir){
if (fs.existsSync(dir)){
return
}
try{
fs.mkdirSync(dir)
}catch(err){
if(err.code == 'ENOENT'){
myMkdirSync(path.dirname(dir)) //create parent dir
myMkdirSync(dir) //create dir
}
}
}
myMkdirSync(path.dirname(filePath));
var file = fs.createWriteStream(filePath);
回答by Kailash
Here is my function which works in Node 10.12.0. Hope this will help.
这是我在 Node 10.12.0 中工作的函数。希望这会有所帮助。
const fs = require('fs');
function(dir,filename,content){
fs.promises.mkdir(dir, { recursive: true }).catch(error => { console.error('caught exception : ', error.message); });
fs.writeFile(dir+filename, content, function (err) {
if (err) throw err;
console.info('file saved!');
});
}
回答by Muhammad Numan
With node-fs-extra you can do it easily.
使用 node-fs-extra,您可以轻松完成。
Install it
安装它
npm install --save fs-extra
Then use the outputFilemethod instead of writeFileSync
然后使用outputFile方法而不是writeFileSync
const fs = require('fs-extra');
fs.outputFile('tmp/test.txt', 'Hey there!', err => {
if(err) {
console.log(err);
} else {
console.log('The file was saved!');
}
})
回答by Luat Do
let name = "./new_folder/" + file_name + ".png";
await driver.takeScreenshot().then(
function(image, err) {
require('mkdirp')(require('path').dirname(name), (err) => {
require('fs').writeFile(name, image, 'base64', function(err) {
console.log(err);
});
});
}
);
回答by David Braun
Here's part of Myrne Stol's answer broken out as a separate answer:
以下是 Myrne Stol 的部分答案,作为单独的答案分解:
This module does what you want: https://npmjs.org/package/writefile. Got it when googling for "writefile mkdirp". This module returns a promise instead of taking a callback, so be sure to read some introduction to promises first. It might actually complicate things for you.
这个模块做你想做的:https://npmjs.org/package/writefile。在谷歌搜索“writefile mkdirp”时得到了它。这个模块返回一个promise而不是一个回调,所以一定要先阅读一些promise的介绍。它实际上可能会让你的事情复杂化。

