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

时间:2012-12-04 04:34:24

标签: 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);
    }
});

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

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

14 个答案:

答案 0 :(得分:226)

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

$ npm install mkdirp

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

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

    // path exists unless there was an error

});

答案 1 :(得分:149)

修改 由于此答案非常受欢迎,因此我对其进行了更新,以反映最新的做法。

使用try {} catch (err) {},您可以非常优雅地实现这一目标,而不会遇到竞争条件。

为了防止检查存在和创建目录之间的死时间,我们只是尝试直接创建它,如果它是EEXIST(目录已经存在),则忽略错误。

但是,如果错误不是EEXIST,我们应该抛出错误,因为我们可能会处理类似EPERMEACCES

的错误

我们还可以使用recursive的{​​{1}}选项,以获得mkdir之类的行为(注意:仅在Node> = 10.x中可用)

同步版本

mkdir -p

异步版本(async / await,现代节点版本)

const fs = require('fs')

function ensureDirSync (dirpath) {
  try {
    fs.mkdirSync(dirpath, { recursive: true })
  } catch (err) {
    if (err.code !== 'EEXIST') throw err
  }
}

try {
  ensureDirSync('a/b/c')
  console.log('Directory created')
} catch (err) {
  console.error(err)
}

如果您不想使用实验性的const fs = require('fs').promises async function ensureDir (dirpath) { try { await fs.mkdir(dirpath, { recursive: true }) } catch (err) { if (err.code !== 'EEXIST') throw err } } async function main () { try { await ensureDir('a/b/c') console.log('Directory created') } catch (err) { console.error(err) } } main() API(虽然它很稳定,并且可以保留),您可以自己包装fs.promises

fs.mkdir

异步版本(承诺,旧版Node)

注意:因为我们在10.x之前的节点版本中没有新的await new Promise((resolve, reject) => { fs.mkdir(dirpath, { recursive: true }, err => err ? reject(err) : resolve()) }) 选项,所以我们必须确保创建路径的每个部分。

recursive

答案 2 :(得分:52)

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

Err.Raise

答案 3 :(得分:26)

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

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

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

答案 4 :(得分:22)

您可以使用:

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

答案 5 :(得分:5)

我提出了一个没有模块的解决方案(从不建议累积模块用于可维护性,特别是对于可以用几行编写的小函数...):

最后更新:

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

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

更新:

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

答案 6 :(得分:4)

以下是我用来创建目录的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}`)
});

注意:

  • createDirectory函数的开头,我规范化路径以保证操作系统的路径分隔符类型将被一致地使用(例如,这会将C:\directory/test变为C:\directory\test (当在Windows上时)
  • fs.existsdeprecated,这就是我使用fs.stat检查目录是否已存在的原因
  • 如果目录不存在,则错误代码为ENOENT E rror NO ENT ry)
  • 将使用fs.mkdir
  • 创建目录本身
  • 我更喜欢异步函数fs.mkdir而不是阻塞对应fs.mkdirSync,并且由于包装Promise,将保证只返回目录的路径成功创建目录后

答案 7 :(得分:3)

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

答案 8 :(得分:3)

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

示例代码:

int main (void)
{

  // disable gprof ?
  uninteresting_routine();
  // enable gprof ?

  interesting_routine();
}

这里的文档:https://github.com/jprichardson/node-fs-extra#mkdirsdir-callback

答案 9 :(得分:1)

  

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

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

答案 10 :(得分:0)

Raugaral's answer,但具有-p功能。丑陋,但可行:

function mkdirp(dir) {
    let dirs = dir.split(/\\/).filter(asdf => !asdf.match(/^\s*$/))
    let fullpath = ''

    // Production directory will begin \\, test is on my local drive.
    if (dirs[0].match(/C:/i)) {
        fullpath = dirs[0] + '\\'
    }
    else {
        fullpath = '\\\\' + dirs[0] + '\\'
    }

    // Start from root directory + 1, build out one level at a time.
    dirs.slice(1).map(asdf => {
        fullpath += asdf + '\\'
        if (!fs.existsSync(fullpath)) {
            fs.mkdirSync(fullpath)
        }
    })
}//mkdirp

答案 11 :(得分:0)

作为Teemu Ikonen's answer的一种较新的替代方法,它非常简单且易于阅读,就是使用ensureDir包中的fs-extra方法。

它不仅可以用作内置fs模块的公然替代品,而且还具有fs包功能之外的许多其他功能。

顾名思义,ensureDir方法可确保该目录存在。如果目录结构不存在,则会创建它。像mkdir -p。不只是结束文件夹,如果还不存在,则会创建整个路径。

上面提供的是它的async版本。它还具有一种ensureDirSync方法形式的同步方法。

答案 12 :(得分:0)

您可以使用文件系统模块来完成所有这些操作。

const
  fs = require('fs'),
  dirPath = `path/to/dir`

// Check if directory exists.
fs.access(dirPath, fs.constants.F_OK, (err)=>{
  if (err){
    // Create directory if directory does not exist.
    fs.mkdir(dirPath, {recursive:true}, (err)=>{
      if (err) console.log(`Error creating directory: ${err}`)
      else console.log('Directory created successfully.')
    })
  }
  // Directory now exists.
})

您甚至根本不需要检查目录是否存在。以下代码还保证该目录已经存在或已创建。

const
  fs = require('fs'),
  dirPath = `path/to/dir`

// Create directory if directory does not exist.
fs.mkdir(dirPath, {recursive:true}, (err)=>{
  if (err) console.log(`Error creating directory: ${err}`)
  // Directory now exists.
})

答案 13 :(得分:0)

@Liberateur的answer above对我不起作用(节点v8.10.0)。 稍加修改就可以解决问题,但是我不确定这是否正确。请提出建议。

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

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

// Create folder path
mkdirpath('my/new/folder/create');