节点如何创build一个目录如果不存在?
这是创build一个不存在的目录的正确方法。 它应该有脚本的完全许可和其他人可读。
var dir = __dirname + '/upload'; if (!path.existsSync(dir)) { fs.mkdirSync(dir, 0744); }
var fs = require('fs'); var dir = './tmp'; if (!fs.existsSync(dir)){ fs.mkdirSync(dir); }
不,由于多种原因。
-
path
模块没有exists
/existsSync
方法。 它在fs
模块中。 (也许你只是在你的问题上犯了一个错字?) -
该文件显然不鼓励你使用
exists
。fs.exists()
是一个时代错误,只存在于历史原因。 几乎从来没有理由在你自己的代码中使用它。特别是,在打开文件之前检查文件是否存在是一种反模式,使您容易受到竞争状况的影响:另一个进程可能会在调用
fs.exists()
和fs.open()
之间删除文件。 只要打开文件并在不存在的情况下处理错误。由于我们正在讨论一个目录而不是文件,这个build议意味着你应该无条件地调用
mkdir
并忽略EEXIST
。 -
一般来说,你应该避免*
Sync
方法。 他们阻止,这意味着当你去到磁盘时,你的程序中绝对没有别的东西可以发生。 这是一个非常昂贵的操作,所花费的时间打破了节点事件循环的核心假设。*
Sync
方法通常在单一用途的快速脚本(那些只做一件事然后退出的脚本)中很好,但在编写服务器时几乎不会被使用:服务器将无法响应任何人I / O请求的持续时间。 如果多个客户端请求需要I / O操作,您的服务器将会很快停止。
我唯一考虑在服务器应用程序中使用*
Sync
方法是在启动时只发生一次 (且只发生一次)的操作。 例如,require
实际上使用readFileSync
来加载模块。即使如此,仍然要小心,因为许多同步I / O可能会不必要地减慢服务器的启动时间。
相反,您应该使用asynchronousI / O方法。
所以如果我们把这些build议放在一起,我们得到这样的东西:
function ensureExists(path, mask, cb) { if (typeof mask == 'function') { // allow the `mask` parameter to be optional cb = mask; mask = 0777; } fs.mkdir(path, mask, function(err) { if (err) { if (err.code == 'EEXIST') cb(null); // ignore the error if the folder already exists else cb(err); // something else went wrong } else cb(null); // successfully created folder }); }
我们可以像这样使用它:
ensureExists(__dirname + '/upload', 0744, function(err) { if (err) // handle folder creation error else // we're all good });
当然,这不包括像边缘情况
- 如果文件夹在程序运行时被删除会发生什么? (假设你只在启动时检查它是否存在一次)
- 如果文件夹已经存在,但是权限错误,会发生什么情况?
我发现和npm模块就像这样的魅力。 只需要做一个recursion的mkdir,就像“mkdir -p”一样。
最好的解决scheme是使用名为node-fs-extra的npm模块。 它有一个名为mkdir
的方法,它创build你提到的目录。 如果你给一个长的目录path,它会自动创build父文件夹。 该模块是npm模块fs
的超级集合,所以如果添加此模块,则可以使用fs
所有函数。
我想给josh3736的答案添加一个Typescript Promise重构。
它做同样的事情,并具有相同的边缘情况下,它恰好使用承诺,typescript typedefs和“严格使用”的作品。
// 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 } }); }); }
var filessystem = require('fs'); var dir = './path/subpath/'; if (!filessystem.existsSync(dir)){ filessystem.mkdirSync(dir); }else { console.log("Directory already exist"); }
这可能会帮助你:)
var dir = 'path/to/dir'; try { fs.mkdirSync(dir); } catch(e) { if (e.code ~= 'EEXIST') throw e; }
这里是一个小函数来recursion创build目录:
const createDir = (dir) => { // This will create a dir given a path such as './folder/subfolder' const splitPath = dir.split('/'); splitPath.reduce((path, subPath) => { let currentPath; if(subPath != '.'){ currentPath = path + '/' + subPath; if (!fs.existsSync(currentPath)){ fs.mkdirSync(currentPath); } } else{ currentPath = subPath; } return currentPath }, '') }