我一直在摆弄Node.js,发现了一个小问题。我有一个脚本驻留在一个名为data的目录中。我希望脚本将一些数据写入数据子目录中的子目录中的文件。然而,我得到以下错误:

{ [Error: ENOENT, open 'D:\data\tmp\test.txt'] errno: 34, code: 'ENOENT', path: 'D:\\data\\tmp\\test.txt' }

代码如下:

var fs = require('fs');
fs.writeFile("tmp/test.txt", "Hey there!", function(err) {
    if(err) {
        console.log(err);
    } else {
        console.log("The file was saved!");
    }
}); 

有人能帮我找出如何使Node.js创建目录结构,如果它不退出写入文件?


当前回答

下面是一个完整的解决方案,在一个函数中创建包含所有所需子文件夹的文件夹,然后写入文件。

这是一个示例,假设您正在创建一个备份文件,并且希望在函数中传递备份文件夹名称(因此变量名称)


  createFile(backupFolderName, fileName, fileContent) {
    const csvFileName = `${fileName}.csv`;

    const completeFilePath = join(process.cwd(), 'backups', backupFolderName);

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

    fs.writeFileSync(join(completeFilePath, csvFileName), fileContent, function (err) {
      if (err) throw err;
      console.log(csvFileName + ' file saved');
    })
  }

其他回答

节点> 10.12.0

fs。Mkdir现在接受一个{recursive: true}选项,如下所示:

// Creates /tmp/a/apple, regardless of whether `/tmp` and /tmp/a exist.
fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
  if (err) throw err;
});

或者带着承诺:

fs.promises.mkdir('/tmp/a/apple', { recursive: true }).catch(console.error);

指出,

在很多情况下你会使用fs。mkdirSync而不是fs.mkdir 在后面加上斜杠是无害的/没有效果的。 mkdirSync/mkdir没有任何伤害,如果目录已经存在,不需要检查是否存在。

节点<= 10.11.0

您可以使用mkdirp或fs-extra这样的包来解决这个问题。如果你不想安装一个软件包,请参阅Tiago Peres França下面的回答。

下面是一个完整的解决方案,在一个函数中创建包含所有所需子文件夹的文件夹,然后写入文件。

这是一个示例,假设您正在创建一个备份文件,并且希望在函数中传递备份文件夹名称(因此变量名称)


  createFile(backupFolderName, fileName, fileContent) {
    const csvFileName = `${fileName}.csv`;

    const completeFilePath = join(process.cwd(), 'backups', backupFolderName);

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

    fs.writeFileSync(join(completeFilePath, csvFileName), fileContent, function (err) {
      if (err) throw err;
      console.log(csvFileName + ' file saved');
    })
  }

如果你不想使用任何额外的包,你可以在创建文件之前调用下面的函数:

var path = require('path'),
    fs = require('fs');

function ensureDirectoryExistence(filePath) {
  var dirname = path.dirname(filePath);
  if (fs.existsSync(dirname)) {
    return true;
  }
  ensureDirectoryExistence(dirname);
  fs.mkdirSync(dirname);
}

无耻的插头警报!

您必须检查您想要的路径结构中的每个目录,如果不存在则手动创建它。在Node的fs模块中已经有了所有这样做的工具,但是您可以简单地使用我的mkpath模块:https://github.com/jrajav/mkpath

我的建议是:当你可以用几行代码轻松完成时,尽量不要依赖依赖项

以下是你试图在14行代码中实现的目标:

fs.isDir = function(dpath) {
    try {
        return fs.lstatSync(dpath).isDirectory();
    } catch(e) {
        return false;
    }
};
fs.mkdirp = function(dirname) {
    dirname = path.normalize(dirname).split(path.sep);
    dirname.forEach((sdir,index)=>{
        var pathInQuestion = dirname.slice(0,index+1).join(path.sep);
        if((!fs.isDir(pathInQuestion)) && pathInQuestion) fs.mkdirSync(pathInQuestion);
    });
};