我已经阅读过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文档,其中包含有关错误对象包含哪些内容的详细信息,以及哪些参数表示等。
答案 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
,我们应该抛出错误,因为我们可能会处理类似EPERM
或EACCES
我们还可以使用recursive
的{{1}}选项,以获得mkdir
之类的行为(注意:仅在Node> = 10.x中可用)
mkdir -p
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
注意:因为我们在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.exists
为deprecated,这就是我使用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');