繁体   English   中英

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

[英]Node.js create folder or use existing

我已经阅读了 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 的完整或至少更详细的文档,其中包含有关错误对象包含的内容、参数表示的内容等的详细信息。

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

$ npm install mkdirp

使用它来运行需要目录的函数。 创建路径后或路径已存在时调用回调。 如果 mkdirp 创建目录路径失败,则会设置错误err

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

    // path exists unless there was an error

});

编辑:因为这个答案很受欢迎,所以我更新了它以反映最新的做法。

节点 >=10

Node 的fs的新{ recursive: true }选项现在允许这样做。 此选项模仿 UNIX 的mkdir -p的行为。 它将递归地确保路径的每个部分都存在,并且如果其中任何一个部分存在,则不会抛出错误。

(注意:它可能仍会抛出EPERMEACCESS等错误,因此如果您的实现容易受到影响,最好还是将其包装在try {} catch (e) {} 。)

同步版本。

fs.mkdirSync(dirpath, { recursive: true })

异步版本

await fs.promises.mkdir(dirpath, { recursive: true })

较旧的节点版本

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

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

然而,如果错误不是EEXIST ,我们应该抛出一个错误,因为我们可能正在处理像EPERMEACCES这样的东西

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

对于./a/b/c mkdir -p的递归行为,例如./a/b/c ,您必须在目录路径的每个部分都调用它,例如./a./a/b.a/b/c

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

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

fs.mkdir的 node.js 文档基本上fs.mkdir mkdir(2)的 Linux 手册页。 这表明如果路径存在但不是一个目录,如果你走这条路,它会产生一个尴尬的极端情况,那么EEXIST也会被指示。

您最好调用fs.stat ,它会告诉您路径是否存在以及它是否是单个调用中的目录。 对于(我假设的是)目录已经存在的正常情况,它只是一个文件系统命中。

这些fs模块方法是原生 C API 的薄包装,因此您必须查看 node.js 文档中引用的手册页以获取详细信息。

你可以使用这个:

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

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

最后更新 :

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

你也可以使用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')

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

这是我用来创建目录的 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.exists弃用,这就是我使用fs.stat检查目录是否已存在的原因
  • 如果目录不存在,错误代码将为ENOENT ( E rror NO ENT ry)
  • 目录本身将使用fs.mkdir创建
  • 我更喜欢异步函数fs.mkdir而不是阻塞对应的fs.mkdirSync并且由于包装Promise ,它将保证目录的路径只会在目录成功创建后返回

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

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

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

正如Teemu Ikonen 的答案(非常简单且易于阅读)的更新替代方案一样,是使用fs-extra包的ensureDir方法。

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

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

上面提供的是它的async版本。 它还有一个同步方法,以ensureDirSync方法的形式执行此ensureDirSync

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

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

@Liberateur上面回答对我不起作用(Node 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');
const fs = require('fs');

const folderName = '/Users/joe/test';

try {
  if (!fs.existsSync(folderName)) {
    fs.mkdirSync(folderName);
  }
} catch (err) {
  console.error(err);
}

有关文档和更多示例,请参阅此处https://nodejs.dev/learn/working-with-folders-in-nodejs

Raugoral 的答案,但具有 -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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM