Node.js创建文件夹或使用现有文件夹

Jos*_*eph 173 javascript node.js

我已经阅读过Node.js的文档,除非我错过了什么,否则它不会告诉某些参数在某些操作中包含的内容,特别是fs.mkdir().正如您在文档中看到的那样,它并不是很多.

目前,我有这个代码,它试图创建一个文件夹或使用现有的文件夹:

fs.mkdir(path,function(e){
    if(!e || (e && e.code === 'EEXIST')){
        //do something with contents
    } else {
        //debug
        console.log(e);
    }
});
Run Code Online (Sandbox Code Playgroud)

但我想知道这是正确的方法吗?检查代码EEXIST是否正确,知道该文件夹已存在?我知道fs.stat()在创建目录之前我可以做,但这已经是文件系统的两次点击了.

其次,是否有完整的或至少更详细的Node.js文档,其中包含有关错误对象包含的内容,哪些参数表示等的详细信息.

Tee*_*nen 233

这样做的好方法是使用mkdirp模块.

$ npm install mkdirp
Run Code Online (Sandbox Code Playgroud)

用它来运行需要该目录的函数.在创建路径或路径确实存在之后调用回调.err如果mkdirp无法创建目录路径,则会设置错误.

var mkdirp = require('mkdirp');
mkdirp('/tmp/some/path/foo', function(err) { 

    // path exists unless there was an error

});
Run Code Online (Sandbox Code Playgroud)

  • @ 1j01如果平台本身支持该操作,我不相信正确的方法是使用模块.这是一条混乱的道路.我必须同意从技术角度来看有更好的答案. (13认同)
  • @RicardoPedroni正确的方法是使用模块.模块通常全心全意地试图解决一个问题,并且经常被维护.您可以使用npm轻松更新它们.此外,您应该特别避免使用fs.exists [Sync],因为它的使用意味着竞争条件. (4认同)
  • 在我看来,使用`fs.exists(Sync)`的@Raugaral,正确的(读取'无依赖性添加')答案将是低调的. (3认同)
  • @1j01此外,使用同步操作意味着竞争条件,因为它们的使用是对它们的解决。 (2认同)
  • 为什么不使用内部节点“fs”功能? (2认同)

Chr*_*ois 162

使用a { recursive: true },你可以非常优雅地实现这一点,而不会遇到竞争条件:

容错 fs

fs.mkdirSync(dirpath, { recursive: true })
Run Code Online (Sandbox Code Playgroud)

注意:mkdir -p用作参数而不是EPERM诸如Node的官方文档中使用的参数EACCESS,以避免与Node的标准路径模块混淆.

说明

Node将尝试创建目录,并在遇到异常时抛出异常.在该try {} catch (e) {}子句中,我们继续执行脚本,就好像错误代码没有发生一样try {} catch (err) {},这意味着该目录存在.如果错误代码不是EEXIST,我们应该抛出一个错误,因为我们可能正在处理文件系统异常,例如EEXIST(权限被拒绝).

因为在检查存在和创建目录之间没有死时间,所以我们避免竞争条件; 然而,这只能在使用同步版本时才会出现(因此EPERM不起作用),但破坏性文件系统操作(例如EACCES应该只能同步使用).

编辑:我已经找到了一种方法来使相同的概念适应mkdir -p你可以在我的这个要点中找到的异步

例子

让我们创建目录,./a/b/c./a给出:

await fs.promises.mkdir(dirpath, { recursive: true })
Run Code Online (Sandbox Code Playgroud)

线性使用

使用上面的包装函数,您可以确保目录存在并以简单的方式创建它们.

function ensureDirSync (dirpath) {
  try {
    return fs.mkdirSync(dirpath)
  } catch (err) {
    if (err.code !== 'EEXIST') throw err
  }
}
Run Code Online (Sandbox Code Playgroud)

注意:您仍然必须确保目录路径的每个部分都存在../a/b直接调用而不确定.a/b/c{ recursive: true }存在仍然会抛出异常.

像UNIX这样的递归用法 fs

为了避免上述缺陷,您可以mkdir -p在递归函数中进一步包含我们的容错,以确保路径的每个部分都存在:

fs.mkdirSync(dirpath, { recursive: true })
Run Code Online (Sandbox Code Playgroud)

  • 警告:如果您的路径以 / 开头,则不起作用 (2认同)

mar*_*tur 55

如果你想要一个快速而又脏的衬里,请使用:

fs.existsSync("directory") || fs.mkdirSync("directory");
Run Code Online (Sandbox Code Playgroud)

  • 但是,fs.existsSync(...)并没有被弃用,所以这个答案似乎没问题. (6认同)
  • `fs.exists` 已弃用:https://nodejs.org/api/fs.html#fs_fs_exists_path_callback (2认同)

Joh*_*yHK 26

node.js文档fs.mkdir基本上适用于Linux手册页mkdir(2).这表明EEXIST如果路径存在,也将指示,但如果你走这条路线,它不是一个创建一个尴尬的角落案例的目录.

你可能最好不要打电话fs.stat告诉你路径是否存在以及它是否是单个呼叫中的目录.对于(我假设的是)目录已经存在的正常情况,它只是单个文件系统命中.

这些fs模块方法是本机C API的精简包装器,因此您必须检查node.js文档中引用的手册页以获取详细信息.

  • 在"mkdir"之前调用`stat`有可能出现竞争条件 - 请记住这一点. (19认同)

Rau*_*ral 24

你可以用这个:

if(!fs.existsSync("directory")){
    fs.mkdirSync("directory", 0766, function(err){
        if(err){
            console.log(err);
            // echo the result back
            response.send("ERROR! Can't make the directory! \n");
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 根据http://nodejs.org/api/fs.html#fs_fs_mkdirsync_path_mode,mkdir的Sync变体不接受回调 (5认同)
  • 对不起,我错了.更改"existsSync"的"statSync" (2认同)

Lib*_*eur 5

我提出了一种不带模块的解决方案(从不建议使用累积模块来提高可维护性,尤其是对于可以用几行编写的小功能...):

最后更新 :

在v10.12.0中,NodeJS实现的递归选项:

// Create recursive folder
fs.mkdir('my/new/folder/create', { recursive: true }, (err) => { if (err) throw err; });
Run Code Online (Sandbox Code Playgroud)

更新:

// Get modules node
const fs   = require('fs');
const path = require('path');

// Create 
function mkdirpath(dirPath)
{
    if(!fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK))
    {
        try
        {
            fs.mkdirSync(dirPath);
        }
        catch(e)
        {
            mkdirpath(path.dirname(dirPath));
            mkdirpath(dirPath);
        }
    }
}

// Create folder path
mkdirpath('my/new/folder/create');
Run Code Online (Sandbox Code Playgroud)