首页 文章

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

提问于
浏览
151

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

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

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

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

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

11 回答

  • 26

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

    $ npm install mkdirp
    

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

    var mkdirp = require('mkdirp');
    mkdirp('/tmp/some/path/foo', function(err) { 
    
        // path exists unless there was an error
    
    });
    
  • 143

    使用 try {} catch {} ,您可以非常优雅地实现此目的而不会遇到竞争条件:

    容错fs.mkdirSync(dirPath)

    const mkdirSync = function (dirPath) {
      try {
        fs.mkdirSync(dirPath)
      } catch (err) {
        if (err.code !== 'EEXIST') throw err
      }
    }
    

    注意: dirPath 用作参数而不是 path ,例如在Node的 fs.mkdirSync 的官方文档中使用,以避免与Node的标准路径模块混淆 .

    解释

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

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

    Edit: 我已经找到了一种方法来使同一个概念适应你可以在这个_1709151中找到的异步 fs.mkdir

    例子

    让我们创建目录 ./first/second/third./first/second/fourth ,给出:

    const fs = require('fs')
    const path = require('path')
    
    const mkdirSync = function (dirPath) {
      try {
        fs.mkdirSync(dirPath)
      } catch (err) {
        if (err.code !== 'EEXIST') throw err
      }
    }
    

    线性使用

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

    mkdirSync(path.resolve('./first'))
    mkdirSync(path.resolve('./first/second'))
    mkdirSync(path.resolve('./first/second/third'))
    mkdirSync(path.resolve('./first/second')) // To demonstrate fault tolerance
    mkdirSync(path.resolve('./first/second/fourth'))
    

    注意:您仍然必须确保目录路径的每个部分都存在 . 直接调用 mkdirSync(path.resolve('./first/second/third')) 而不确定 ./first./first/second 是否仍然会抛出异常 .

    像UNIX的mkdir -p这样的递归用法

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

    const mkdirpSync = function (dirPath) {
      const parts = dirPath.split(path.sep)
    
      // For every part of our path, call our wrapped mkdirSync()
      // on the full path until and including that part
      for (let i = 1; i <= parts.length; i++) {
        mkdirSync(path.join.apply(null, parts.slice(0, i)))
      }
    }
    
    // You can now directly create the two target directories
    mkdirpSync('first/second/third')
    mkdirpSync('first/second/fourth')
    
  • 3

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

    fs.existsSync("directory") || fs.mkdirSync("directory");
    
  • 19

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

    你可能最好调用fs.stat来告诉你路径是否存在,如果它是's a directory in a single call. For (what I' m假设是)目录已经存在的正常情况,它只是一个文件系统命中 .

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

  • 3

    你可以用这个:

    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");
            }
        });
    }
    
  • 1

    在我看来,在Javascript编码时最好不要计算文件系统命中数 . 但是,(1) statmkdir 和(2) mkdir 并检查(或丢弃)错误代码,两种方式都是正确的方法来做你想要的 .

  • 2

    您还可以使用fs-extra,它提供了许多常用的文件操作 .

    示例代码:

    var fs = require('fs-extra')
    
    fs.mkdirs('/tmp/some/long/path/that/prob/doesnt/exist', function (err) {
      if (err) return console.error(err)
      console.log("success!")
    })
    
    fs.mkdirsSync('/tmp/another/path')
    

    docs:https://github.com/jprichardson/node-fs-extra#mkdirsdir-callback

  • 3

    这是我用来创建目录的ES6代码(当它不存在时):

    const fs = require('fs');
    const path = require('path');
    
    function createDirectory(directoryPath) {
      const directory = path.normalize(directoryPath);
    
      return new Promise((resolve, reject) => {
        fs.stat(directory, (error) => {
          if (error) {
            if (error.code === 'ENOENT') {
              fs.mkdir(directory, (error) => {
                if (error) {
                  reject(error);
                } else {
                  resolve(directory);
                }
              });
            } else {
              reject(error);
            }
          } else {
            resolve(directory);
          }
        });
      });
    }
    
    const directoryPath = `${__dirname}/test`;
    
    createDirectory(directoryPath).then((path) => {
      console.log(`Successfully created directory: '${path}'`);
    }).catch((error) => {
      console.log(`Problem creating directory: ${error.message}`)
    });
    

    Note:

    • createDirectory 函数的开头,我规范化路径以保证将始终如一地使用操作系统的路径分隔符类型(例如,这会将 C:\directory/test 变为 C:\directory\test (在Windows上时)

    • fs.existsdeprecated,这就是我使用 fs.stat 来检查目录是否已存在的原因

    • 如果目录不存在,错误代码将为 ENOENTE rror NO ENT ry)

    • 将使用 fs.mkdir 创建目录本身

    • 我更喜欢异步函数 fs.mkdir 而不是它的阻塞对应 fs.mkdirSync ,并且由于包装 Promise ,将保证只有在成功创建目录后才返回目录的路径

  • 46

    我建议更简单:

    // Get modules node
    const fs   = require('fs');
    const path = require('path');
    
    // Create 
    function mkdirpath(dirPath)
    {
        if(!fs.existsSync(dirPath))
        {
            try
            {
                fs.mkdirSync(dirPath);
            }
            catch(e)
            {
                mkdirpath(path.dirname(dirPath));
                mkdirpath(dirPath);
            }
        }
    }
    
    // Create folder path
    mkdirpath('my/new/folder/create');
    
  • -2

    为每个用户创建动态名称目录...使用此代码

    ***suppose email contain user mail address***
    
    var filessystem = require('fs');
    var dir = './public/uploads/'+email;
    
    if (!filessystem.existsSync(dir)){
      filessystem.mkdirSync(dir);
    
    }else
    {
        console.log("Directory already exist");
    }
    
  • 222
    var fs = require('fs');
    
    if (fs.existsSync('temp')) 
    {
    
        console.log('Directory exists, removing...');
        if (fs.existsSync('temp/new.txt')) 
        {
        fs.unlinkSync('temp/new.txt');
        }
        fs.rmdirSync('temp');
    
    }
    fs.mkdirSync('temp');
    if (fs.existsSync('temp')) {
        process.chdir('temp');
        fs.writeFileSync('test.txt', 'This is some test text for the file');
        fs.renameSync('test.txt','new.txt');
        console.log('File has size: ' + fs.statSync('new.txt').size + ' bytes');
        console.log('File contents: ' + fs.readFileSync('new.txt').toString());
    }
    

相关问题