如果它不存在,我正在尝试创建一个完整的路径。
代码如下所示:
var fs = require('fs');
if (!fs.existsSync(newDest)) fs.mkdirSync(newDest);
只要只有一个子目录(像'dir1'这样的newDest),这个代码就可以运行,但是当有一个像''dir1 / dir2'这样的目录路径时,它失败了,错误:ENOENT,没有这样的文件或目录
我希望能够根据需要使用尽可能少的代码行创建完整路径。
我读到fs上有一个递归选项,并尝试这样做
var fs = require('fs');
if (!fs.existsSync(newDest)) fs.mkdirSync(newDest,'0777', true);
我觉得递归创建一个不存在的目录应该很简单。我是否遗漏了某些内容或是否需要解析路径并检查每个目录并创建它(如果它尚不存在)?
我是Node的新手。也许我正在使用旧版本的FS?
一种选择是使用shelljs module
npm install shelljs
var shell = require('shelljs');
shell.mkdir('-p', fullPath);
从该页面:
可用选项:
p:完整路径(如有必要,将创建中间目录)
正如其他人所指出的那样,还有其他更集中的模块。但是,在mkdirp之外,它还有大量其他有用的shell操作(比如grep等......),它适用于windows和* nix
您可以使用下一个功能
const recursiveUpload =(path:string)=> {const paths = path.split(“/”)
fs.mkdirSync(path, { recursive: true })
它的作用是什么:
希望有所帮助!
顺便说一句,在Node v10.12.0中,您可以通过将其作为附加参数来创建递归路径。
const path = require('path');
const fs = require('fs');
let dir = "C:\\temp\\dir1\\dir2\\dir3";
function createDirRecursively(dir) {
if (!fs.existsSync(dir)) {
createDirRecursively(path.join(dir, ".."));
fs.mkdirSync(dir);
}
}
createDirRecursively(dir); //creates dir1\dir2\dir3 in C:\temp
const fullPath = paths.reduce((accumulator, current) => {
fs.mkdirSync(accumulator)
return `${accumulator}/${current}`
})
fs.mkdirSync(fullPath)
return fullPath
}
太多的答案,但这里是一个没有递归的解决方案,通过拆分路径,然后从左到右建立它再次备份
paths
对于那些担心Windows与Linux兼容性的人来说,只需在上面的两个事件中用双反斜杠'\'替换正斜杠,但TBH我们说的是节点fs而不是windows命令行,而前者非常宽容,上面的代码将简单地工作Windows是一个更完整的跨平台解决方案。
fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
if (err) throw err;
});
您可以简单地以递归方式检查文件夹是否存在于路径中,并在检查文件夹是否不存在时创建该文件夹。 (没有外部图书馆)
https://nodejs.org/api/fs.html#fs_fs_mkdirsync_path_options
以递归方式创建目录的异步方法:
function mkdirRecursiveSync(path) {
let paths = path.split(path.delimiter);
let fullPath = '';
paths.forEach((path) => {
if (fullPath === '') {
fullPath = path;
} else {
fullPath = fullPath + '/' + path;
}
if (!fs.existsSync(fullPath)) {
fs.mkdirSync(fullPath);
}
});
};
这是我对nodejs的const fs = require('fs');
try {
fs.mkdirSync(path, { recursive: true });
} catch (error) {
// this make script keep running, even when folder already exist
console.log(error);
}
的命令式版本。
function checkAndCreateDestinationPath (fileDestination) {
const dirPath = fileDestination.split('/');
dirPath.forEach((element, index) => {
if(!fs.existsSync(dirPath.slice(0, index + 1).join('/'))){
fs.mkdirSync(dirPath.slice(0, index + 1).join('/'));
}
});
}
这种方法怎么样:
import fs from 'fs'
const mkdirRecursive = function(path, callback) {
let controlledPaths = []
let paths = path.split(
'/' // Put each path in an array
).filter(
p => p != '.' // Skip root path indicator (.)
).reduce((memo, item) => {
// Previous item prepended to each item so we preserve realpaths
const prevItem = memo.length > 0 ? memo.join('/').replace(/\.\//g, '')+'/' : ''
controlledPaths.push('./'+prevItem+item)
return [...memo, './'+prevItem+item]
}, []).map(dir => {
fs.mkdir(dir, err => {
if (err && err.code != 'EEXIST') throw err
// Delete created directory (or skipped) from controlledPath
controlledPaths.splice(controlledPaths.indexOf(dir), 1)
if (controlledPaths.length === 0) {
return callback()
}
})
})
}
// Usage
mkdirRecursive('./photos/recent', () => {
console.log('Directories created succesfully!')
})
这适用于相对路径。
基于mkdirp
零依赖性答案,这里是一个稍微初学者友好的function mkdirSyncP(location) {
let normalizedPath = path.normalize(location);
let parsedPathObj = path.parse(normalizedPath);
let curDir = parsedPathObj.root;
let folders = parsedPathObj.dir.split(path.sep);
folders.push(parsedPathObj.base);
for(let part of folders) {
curDir = path.join(curDir, part);
if (!fs.existsSync(curDir)) {
fs.mkdirSync(curDir);
}
}
}
变体,作为一个模块:
if (!fs.existsSync(pathToFile)) {
var dirName = "";
var filePathSplit = pathToFile.split('/');
for (var index = 0; index < filePathSplit.length; index++) {
dirName += filePathSplit[index]+'/';
if (!fs.existsSync(dirName))
fs.mkdirSync(dirName);
}
}
像这样干净:)
mouneer's
Exec在windows上可能很乱。有一个更“nodie”的解决方案。从根本上说,您有一个递归调用来查看目录是否存在并潜入子级(如果存在)或创建它。这是一个函数,它将创建子节点并在完成时调用函数:
Typescript
}
编辑
NodeJS版本10.12.0
为mkdir
和mkdirSync
添加了原生支持,以recursive: true
选项递归创建目录,如下所示:
fs.mkdirSync(targetDir, { recursive: true });
如果你更喜欢fs Promises API
,你可以写
fs.promises.mkdir(targetDir, { recursive: true });
如果目录不存在,则递归创建目录! (零依赖)
const fs = require('fs');
const path = require('path');
function mkDirByPathSync(targetDir, { isRelativeToScript = false } = {}) {
const sep = path.sep;
const initDir = path.isAbsolute(targetDir) ? sep : '';
const baseDir = isRelativeToScript ? __dirname : '.';
return targetDir.split(sep).reduce((parentDir, childDir) => {
const curDir = path.resolve(baseDir, parentDir, childDir);
try {
fs.mkdirSync(curDir);
} catch (err) {
if (err.code === 'EEXIST') { // curDir already exists!
return curDir;
}
// To avoid `EISDIR` error on Mac and `EACCES`-->`ENOENT` and `EPERM` on Windows.
if (err.code === 'ENOENT') { // Throw the original parentDir error on curDir `ENOENT` failure.
throw new Error(`EACCES: permission denied, mkdir '${parentDir}'`);
}
const caughtErr = ['EACCES', 'EPERM', 'EISDIR'].indexOf(err.code) > -1;
if (!caughtErr || caughtErr && curDir === path.resolve(targetDir)) {
throw err; // Throw if it's just the last created dir.
}
}
return curDir;
}, initDir);
}
// Default, make directories relative to current working directory.
mkDirByPathSync('path/to/dir');
// Make directories relative to the current script.
mkDirByPathSync('path/to/dir', {isRelativeToScript: true});
// Make directories with an absolute path.
mkDirByPathSync('/path/to/dir');
EISDIR
和适用于Windows的EPERM
和EACCES
。感谢@PediT。,@ JohnQ,@ deed02392,@ robyoder和@Almenon的所有报道评论。{isRelativeToScript: true}
。path.sep
和path.resolve()
,而不仅仅是/
连接,以避免跨平台问题。fs.mkdirSync
并使用try/catch
处理错误,如果抛出来处理竞争条件:另一个进程可能会在调用fs.existsSync()
和fs.mkdirSync()
之间添加文件并导致异常。
实现这一目标的另一种方法是检查文件是否存在然后创建它,即if (!fs.existsSync(curDir) fs.mkdirSync(curDir);
。但这是一种反模式,使代码容易受到竞争条件的影响。感谢@GershomMaes关于目录存在检查的评论。这个版本在Windows上的效果比最佳答案更好,因为它理解import * as fs from 'fs';
import * as path from 'path';
/**
* Recursively creates directories until `targetDir` is valid.
* @param targetDir target directory path to be created recursively.
* @param isRelative is the provided `targetDir` a relative path?
*/
export function mkdirRecursiveSync(targetDir: string, isRelative = false) {
const sep = path.sep;
const initDir = path.isAbsolute(targetDir) ? sep : '';
const baseDir = isRelative ? __dirname : '.';
targetDir.split(sep).reduce((prevDirPath, dirToCreate) => {
const curDirPathToCreate = path.resolve(baseDir, prevDirPath, dirToCreate);
try {
fs.mkdirSync(curDirPathToCreate);
} catch (err) {
if (err.code !== 'EEXIST') {
throw err;
}
// caught EEXIST error if curDirPathToCreate already existed (not a problem for us).
}
return curDirPathToCreate; // becomes prevDirPath on next call to reduce
}, initDir);
}
和function makedir(fullpath) {
let destination_split = fullpath.replace('/', '\\').split('\\')
let path_builder = destination_split[0]
$.each(destination_split, function (i, path_segment) {
if (i < 1) return true
path_builder += '\\' + path_segment
if (!fs.existsSync(path_builder)) {
fs.mkdirSync(path_builder)
}
})
}
,因此正斜杠可以在Windows上运行。支持绝对路径和相对路径(相对于fs = require('fs');
makedirs = function(path, func) {
var pth = path.replace(/['\\]+/g, '/');
var els = pth.split('/');
var all = "";
(function insertOne() {
var el = els.splice(0, 1)[0];
if (!fs.existsSync(all + el)) {
fs.mkdirSync(all + el);
}
all += el + "/";
if (els.length == 0) {
func();
} else {
insertOne();
}
})();
)。
/
一个更健全的答案是使用mkdirp。
var mkdirp = require('mkdirp');
mkdirp('/path/to/dir', function (err) {
if (err) console.error(err)
else console.log('dir created')
});
然后继续将文件写入完整路径:
fs.writeFile ('/path/to/dir/file.dat'....
fs-extra添加了本机fs模块中未包含的文件系统方法。这是对fs的替代。
安装fs-extra
$ npm install --save fs-extra
const fs = require("fs-extra");
// Make sure the output directory is there.
fs.ensureDirSync(newDest);
有同步和异步选项。
https://github.com/jprichardson/node-fs-extra/blob/master/docs/ensureDir.md
使用reduce我们可以验证每个路径是否存在并在必要时创建它,这样我认为它更容易理解。编辑,感谢@Arvin,我们应该使用path.sep来获取适当的特定于平台的路径段分隔符。
const path = require('path');
// Path separators could change depending on the platform
const pathToCreate = 'path/to/dir';
pathToCreate
.split(path.sep)
.reduce((prevPath, folder) => {
const currentPath = path.join(prevPath, folder, path.sep);
if (!fs.existsSync(currentPath)){
fs.mkdirSync(currentPath);
}
return currentPath;
}, '');
此功能已添加到版本10.12.0中的node.js,因此它就像将选项{recursive: true}
作为第二个参数传递给fs.mkdir()
调用一样简单。见example in the official docs。
无需外部模块或您自己的实现。
我知道这是一个老问题,但nodejs v10.12.0现在支持这个本地,recursive
选项设置为true。 fs.mkdir
// Creates /tmp/a/apple, regardless of whether `/tmp` and /tmp/a exist.
fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
if (err) throw err;
});
现在使用Node JS> = qazxsw poi,你可以使用qazxsw poi qazxsw poi
Windows示例(没有额外的依赖项和错误处理)
10.12.0