如何使用Node.js创建一个目录(文件夹)如果它不存在

1145

如果目录不存在,以下是创建目录的正确方法吗?

脚本应该拥有完全权限,并可被其他人阅读。

var dir = __dirname + '/upload';
if (!path.existsSync(dir)) {
    fs.mkdirSync(dir, 0744);
}

4
在提问之前,你尝试运行你的脚本了吗?当我尝试运行时,我收到了 TypeError: path.existsSync is not a function 的错误提示(我正在使用 Node v8.10)。 - Jean Paul
3
根据官方API文档 https://nodejs.org/api/fs.html#fsexistssyncpath,应该使用`fs.existsSync(dir)`而不是`path.existsSync(dir)`。 - xgqfrms
24个回答

8

对于Node v10及以上版本的简单而现代的解决方案

正如一些答案所指出的那样,自从Node 10版本以后,你可以在mkdir中使用recursive:true

但是还没有指出的是,当使用recursive:true时,如果目录已经存在,mkdir不会返回错误

因此,你可以这样做:

fs.mkdir(dirPath,{recursive:true},(err) => {
    if(err) {
        //note: this does NOT get triggered if the directory already existed
        console.warn(err)
    }
    else{
        //directory now exists 
    }
})

使用 Promises

自从 Node 10 版本以后,你可以通过从 fs/promises 引入来获取所有 fs 函数的 Promise 版本

因此,将这两个要素结合起来,你就得到了这个简单的解决方案:

import * as fs from 'fs/promises';

await fs.mkdir(dirPath, {recursive:true}).catch((err) => {
    //decide what you want to do if this failed
    console.error(err);
});

//directory now exists

现代答案 - stackers

8

fs.exist()已经被弃用,所以我使用fs.stat()来检查目录状态。如果目录不存在,fs.stat()会抛出一个错误信息,如“没有这个文件或目录”。然后我创建了一个目录。

const fs = require('fs').promises;

const dir = './dir';
fs.stat(dir).catch(async (err) => {
  if (err.message.includes('no such file or directory')) {
    await fs.mkdir(dir);
  }
});

6

使用:

var filessystem = require('fs');
var dir = './path/subpath/';

if (!filessystem.existsSync(dir))
{
    filessystem.mkdirSync(dir);
}
else
{
    console.log("Directory already exist");
}

需要解释一下(但是不要包含“编辑:”,“更新:”或类似的内容 - 答案应该看起来像是今天写的)。 - Peter Mortensen

6
var dir = 'path/to/dir';
try {
  fs.mkdirSync(dir);
} catch(e) {
  if (e.code != 'EEXIST') throw e;
}

由于existsSync已被弃用。 - Ping.Goblue
4
对于 Node.js v7.4.0,文档指出 fs.exists() 已被废弃,但 fs.existsSync() 并未被废弃。您能否添加一个链接到标明 fs.existsSync() 被废弃的资源? - francis
1
仅提供代码的答案对于未来查看此问题的用户并不是很有帮助。请编辑您的答案,解释您的代码如何解决原始问题。 - yivi
3
@francis,嗯,我在查看Node.js v5的文档,链接为https://nodejs.org/docs/latest-v5.x/api/fs.html#fs_fs_existssync_path。该链接介绍了fs模块中的existsSync()方法。 - Ping.Goblue
1
谢谢!看起来这个函数在0.12版本中存在,被4和5版本弃用,然后在6和7版本中恢复了...有点像僵尸函数... - francis
1
是的,显然截至2018年4月,它并没有被弃用:https://nodejs.org/api/fs.html#fs_fs_existssync_path - LeOn - Han Li

5

对于其他在2023年寻找此功能的人,您现在可以使用async/await - try/catch语法轻松实现:

import { stat, mkdir } from 'node:fs/promises';

const checkAndMakeDirectory = async (dir) => {
  try {
    await stat(dir);
  } catch (error) {
    if (error.code === "ENOENT") {
      try {
        await mkdir(dir);
      } catch (err) {
        console.error(err.message);
      }
    }
  }
}

4

使用 Node.js 10+ 和 ES6

import path from 'path';
import fs from 'fs';

(async () => {
  const dir = path.join(__dirname, 'upload');

  try {
    await fs.promises.mkdir(dir);
  } catch (error) {
    if (error.code === 'EEXIST') {
      // Something already exists, but is it a file or directory?
      const lstat = await fs.promises.lstat(dir);

      if (!lstat.isDirectory()) {
        throw error;
      }
    } else {
      throw error;
    }
  }
})();

3
我想对josh3736的答案进行TypeScript Promise重构。
它完成了同样的功能,并且具有相同的边缘情况,只是使用了Promises、TypeScript typedefs并且与"use strict"一起使用。
// https://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation
const allRWEPermissions = parseInt("0777", 8);

function ensureFilePathExists(path: string, mask: number = allRWEPermissions): Promise<void> {
    return new Promise<void>(
        function(resolve: (value?: void | PromiseLike<void>) => void,
            reject: (reason?: any) => void): void{
            mkdir(path, mask, function(err: NodeJS.ErrnoException): void {
                if (err) {
                    if (err.code === "EEXIST") {
                        resolve(null); // Ignore the error if the folder already exists
                    } else {
                        reject(err); // Something else went wrong
                    }
                } else {
                    resolve(null); // Successfully created folder
                }
            });
    });
}

3

文档中可以看到,以下是异步递归执行的方法:

const fs = require('fs');
const fsPromises = fs.promises;

fsPromises.access(dir, fs.constants.F_OK)
   .catch(async() => {
                await fs.mkdir(dir, { recursive: true }, function(err) {
                    if (err) {
                      console.log(err)
                    }
                  })
    });

2
你可以使用Node.js的文件系统命令fs.stat来检查目录是否存在,使用带有回调函数的fs.mkdir创建目录或者使用不带回调函数的fs.mkdirSync创建目录,就像这个例子一样:

你可以使用Node.js的文件系统命令fs.stat来检查目录是否存在,使用带有回调函数的fs.mkdir创建目录或者使用不带回调函数的fs.mkdirSync创建目录,就像这个例子一样:

// First require fs
const fs = require('fs');

// Create directory if not exist (function)
const createDir = (path) => {
    // Check if dir exist
    fs.stat(path, (err, stats) => {
        if (stats.isDirectory()) {
            // Do nothing
        } else {
            // If the given path is not a directory, create a directory
            fs.mkdirSync(path);
        }
    });
};

2

如果子目录不存在,我需要创建它们。我使用了以下代码:

const path = require('path');
const fs = require('fs');

function ensureDirectoryExists(p) {
    //console.log(ensureDirectoryExists.name, {p});
    const d = path.dirname(p);
    if (d && d !== p) {
        ensureDirectoryExists(d);
    }
    if (!fs.existsSync(d)) {
        fs.mkdirSync(d);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接