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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13696148/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 12:41:33  来源:igfitidea点击:

Node.js create folder or use existing

javascriptnode.js

提问by Joseph

I already have read the documentation of Node.js and, unless if I missed something, it does not tell what the parameters contain in certain operations, in particular fs.mkdir(). As you can see in the documentation, it's not very much.

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

Currently, I have this code, which tries to create a folder or use an existing one instead:

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

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

But I wonder is this the right way to do it? Is checking for the code EEXISTthe right way to know that the folder already exists? I know I can do fs.stat()before making the directory, but that would already be two hits to the filesystem.

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

Secondly, is there a complete or at least a more detailed documentation of Node.js that contains details as to what error objects contain, what parameters signify etc.

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

回答by Teemu Ikonen

Good way to do this is to use mkdirpmodule.

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

$ npm install mkdirp

Use it to run function that requires the directory. Callback is called after path is created or if path did already exists. Error erris set if mkdirp failed to create directory path.

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

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

    // path exists unless there was an error

});

回答by Christophe Marois

Edit:Because this answer is very popular, I have updated it to reflect up-to-date practices.

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

Node >=10

节点 >=10

The new { recursive: true }option of Node's fsnow allows this natively. This option mimics the behaviour of UNIX's mkdir -p. It will recursively make sure every part of the path exist, and will not throw an error if any of them do.

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

(Note: it might still throw errors such as EPERMor EACCESS, so better still wrap it in a try {} catch (e) {}if your implementation is susceptible to it.)

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

Synchronous version.

同步版本。

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

Async version

异步版本

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

Older Node versions

较旧的节点版本

Using a try {} catch (err) {}, you can achieve this very gracefully without encountering a race condition.

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

In order to prevent dead time between checking for existence and creating the directory, we simply try to create it straight up, and disregard the error if it is EEXIST(directory already exists).

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

If the error is not EEXIST, however, we ought to throw an error, because we could be dealing with something like an EPERMor EACCES

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

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

For mkdir -p-like recursive behaviour, e.g. ./a/b/c, you'd have to call it on every part of the dirpath, e.g. ./a, ./a/b, .a/b/c

对于mkdir -p样递归的行为,例如./a/b/c,你必须把它在dirpath的每一个部分,例如./a./a/b.a/b/c

回答by marekventur

If you want a quick-and-dirty one liner, use this:

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

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

回答by JohnnyHK

The node.js docs for fs.mkdirbasically defer to the Linux man page for mkdir(2). That indicates that EEXISTwill also be indicated if the path exists but isn't a directory which creates an awkward corner case if you go this route.

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

You may be better off calling fs.statwhich will tell you whether the path exists and if it's a directory in a single call. For (what I'm assuming is) the normal case where the directory already exists, it's only a single filesystem hit.

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

These fsmodule methods are thin wrappers around the native C APIs so you've got to check the man pages referenced in the node.js docs for the details.

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

回答by Raugaral

You can use this:

你可以使用这个:

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

回答by Liberateur

I propose a solution without modules (accumulate modules is never recommended for maintainability especially for small functions that can be written in a few lines...) :

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

LAST UPDATE :

最后更新 :

In v10.12.0, NodeJS impletement recursive options :

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

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

UPDATE :

更新 :

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

回答by Benny Neugebauer

Here is the ES6 code which I use to create a directory (when it doesn't exist):

这是我用来创建目录的 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:

笔记:

  • In the beginning of the createDirectoryfunction, I normalize the path to guarantee that the path seperator type of the operating system will be used consistently (e.g. this will turn C:\directory/testinto C:\directory\test(when being on Windows)
  • fs.existsis deprecated, that's why I use fs.statto check if the directory already exists
  • If a directory doesn't exist, the error code will be ENOENT(Error NO ENTry)
  • The directory itself will be created using fs.mkdir
  • I prefer the asynchronous function fs.mkdirover it's blocking counterpart fs.mkdirSyncand because of the wrapping Promiseit will be guaranteed that the path of the directory will only be returned after the directory has been successfully created
  • createDirectory函数的开头,我对路径进行了规范化,以保证操作系统的路径分隔符类型将被一致使用(例如这将C:\directory/test变成C:\directory\test(在Windows上时)
  • fs.exists弃用,这就是我fs.stat用来检查目录是否已存在的原因
  • 如果目录不存在,错误代码将是ENOENT( Error NO ENTry)
  • 目录本身将使用 fs.mkdir
  • 我更喜欢异步函数而fs.mkdir不是它的阻塞对应物,fs.mkdirSync并且由于包装Promise,它将保证目录的路径只会在目录成功创建后返回

回答by Geng Jiawen

You can also use fs-extra, which provide a lot frequently used file operations.

你也可以使用fs-extra,它提供了很多常用的文件操作。

Sample Code:

示例代码:

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 here: https://github.com/jprichardson/node-fs-extra#mkdirsdir-callback

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

回答by Chul-Woong Yang

You'd better not to count the filesystem hits while you code in Javascript, in my opinion. However, (1) stat& mkdirand (2) mkdirand check(or discard) the error code, both ways are right ways to do what you want.

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

回答by Adiii

create dynamic name directory for each user... use this code

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

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