如果父文件夹不存在,如何写文件?

我需要将文件写入以下路径:

fs.writeFile('/folder1/folder2/file.txt', 'content', function () {…});

但是 '/folder1/folder2'路径可能不存在,因此我得到以下错误:

Message = ENOENT,open/folder1/folder2/file.txt

如何将内容写入该路径?

111648 次浏览

你可以用

fs.stat('/folder1/folder2', function(err, stats){ ... });

statsfs.Stats类型的对象,您可以检查 stats.isDirectory()。根据 errstats的检查,你可以做一些事情,fs.mkdir( ... )或抛出一个错误。

参考文献

更新: 修正了代码中的逗号。

从 Node v10开始,这是内置在 fs.mkdir函数中的,我们可以将它与 Path.dirname结合使用:

var fs = require('fs');
var getDirName = require('path').dirname;


function writeFile(path, contents, cb) {
fs.mkdir(getDirName(path), { recursive: true}, function (err) {
if (err) return cb(err);


fs.writeFile(path, contents, cb);
});
}

对于旧版本,您可以使用 Mkdirp:

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

如果整个路径已经存在,则 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.

我给出的函数在任何情况下都适用。

也许最简单的方法就是使用 F-path npm 模块。

你的代码看起来就像:

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

Here's part of Myrne Stol's answer broken out as a separate answer:

这个模块完成您想要的任务: https://npmjs.org/package/writefile。 在搜索“ writefile mkdirp”时得到它 承诺而不是接受复试,所以一定要读一些 introduction to promises first. It might actually complicate things 为了你。

下面是递归创建目录的自定义函数(没有外部依赖项) :

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

剪辑

NodeJS 版本 10.12.0增加了对 mkdirmkdirSync的本机支持,以递归方式使用 recursive: true选项创建父控制器,如下所示:

fs.mkdirSync(targetDir, { recursive: true });

如果你喜欢 fs Promises API,你可以写

fs.promises.mkdir(targetDir, { recursive: true });

原始答案

如果父目录不存在,则递归地创建它们! (零依赖)

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

用法

// 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');

演示

Try It!

解释

  • [ UPDATE ] 此解决方案处理特定于平台的错误,如 Mac 的 EISDIR、 Windows 的 EPERMEACCES
  • 此解决方案同时处理 亲戚绝对的路径。
  • 对于相对路径,目标目录将在当前工作目录中创建(解析)。若要相对于当前脚本目录解析它们,请传递 {isRelativeToScript: true}
  • 使用 path.seppath.resolve(),而不仅仅是 /连接,以避免跨平台问题。
  • 如果抛出 try/catch来处理竞态条件,则使用 fs.mkdirSync并处理该错误: 另一个进程可能会在对 fs.existsSync()fs.mkdirSync()的调用之间添加文件,从而导致异常。
    • 另一种方法是检查文件是否存在,然后创建它,即 if (!fs.existsSync(curDir) fs.mkdirSync(curDir);。但是这是一个反模式,使代码容易受到竞态条件的影响。
  • 需要 节点 V6和更新的支持解构。(如果您在使用旧的 Node 版本实现此解决方案时遇到问题,请给我留言)

我发现最简单的方法是使用 额外的模块中的 一个 href = “ https://github.com/jprichardson/node-fs-tra/blob/master/docs/outputFile.md”rel = “ norefrer”> 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().

例如:

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

它也有承诺支持的盒子这些天。

这是我在 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!');
});
}

使用 node-fs-tra,可以很容易地完成这项工作。

安装它

npm install --save fs-extra

然后使用 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!');
}
})
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);
});
});
}
);

在 Windows 中,您可以使用以下代码:

 try {
fs.writeFileSync(  './/..//..//filename.txt' , 'the text to write in the file', 'utf-8' );
}
catch(e){
console.log(" catch XXXXXXXXX ");
}

此代码在 Windows 中创建位于当前文件夹上方2个文件夹中的文件。

但是我不能用 C: 直接创建文件