노드의 fs.mkdirSync로 전체 경로를 만드는 방법은 무엇입니까?
만약 그것이 존재하지 않는다면 나는 전체 경로를 만들려고 노력하고 있습니다.
코드는 다음과 같습니다.
var fs = require('fs');
if (!fs.existsSync(newDest)) fs.mkdirSync(newDest);
이 코드는 하위 디렉터리('dir1'과 같은 새 Dest)가 하나만 있으면 잘 작동하지만('dir1/dir2'와 같은 디렉터리 경로가 있으면 오류: ENOENT, 해당 파일 또는 디렉터리 없음)와 함께 실패합니다.
필요한 만큼 코드 줄 수 있는 전체 경로를 만들 수 있으면 좋겠습니다.
재귀 옵션이 있는 것을 읽고 이렇게 시도했습니다.
var fs = require('fs');
if (!fs.existsSync(newDest)) fs.mkdirSync(newDest,'0777', true);
존재하지 않는 디렉터리를 재귀적으로 만드는 것이 그렇게 간단해야 한다고 생각합니다.경로를 분석하여 각 디렉터리를 확인하고 디렉터리가 없는 경우 생성해야 합니까?
노드는 처음입니다.제가 오래된 버전의 FS를 사용하고 있는 것이 아닐까요?
갱신하다
JS 버전10.12.0
두 가지 모두에 대한 기본 지원이 추가되었습니다.mkdir
그리고.mkdirSync
다음과 같은 옵션을 사용하여 디렉터리를 재귀적으로 만듭니다.
fs.mkdirSync(targetDir, { recursive: true });
그리고 당신이 원한다면, 당신은 쓸 수 있습니다.
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');
데모
설명
- [UPDATE] 이 솔루션은 다음과 같은 플랫폼별 오류를 처리합니다.
EISDIR
및 »EPERM
그리고.EACCES
@ 모든.@PediT., @JohnQ, @deed02392, @robyoder @Almenon 의든고견다니덕입분. - 이 솔루션은 상대 경로와 절대 경로를 모두 처리합니다.@john 댓글 덕분입니다.
- 상대 경로의 경우 대상 디렉토리가 현재 작업 디렉토리에 작성(해결)됩니다.dir에 하려면 현재에스트립상대로으문적제다해통다과니합음을면려하결를크▁pass▁to다니통▁dir▁relative합과▁them를 전달합니다.
{isRelativeToScript: true}
. - 및 를 사용하는 것은(는)
/
교차 플랫폼 문제를 방지하기 위한 연결. - 오류 사용 및 처리 방법
try/catch
레이스 조건을 처리하기 위해 던져진 경우: 다른 프로세스가 에 대한 호출 사이에 파일을 추가하고 예외를 발생시킬 수 있습니다.- 파일이 존재하는지 확인한 후 파일을 생성하는 것도 다른 방법일 수 있습니다.
if (!fs.existsSync(curDir) fs.mkdirSync(curDir);
그러나 이것은 코드를 인종 조건에 취약하게 만드는 안티패턴입니다.디렉토리 존재 확인에 대한 @GershomMaes 의견 덕분입니다.
- 파일이 존재하는지 확인한 후 파일을 생성하는 것도 다른 방법일 수 있습니다.
- 파괴를 지원하려면 노드 v6 이상이 필요합니다. (이전 노드 버전에서 이 솔루션을 구현하는 데 문제가 있으면 의견을 남겨 주십시오.)
더 강력한 답변은 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'....
한 가지 옵션은 shelljs 모듈을 사용하는 것입니다.
npm 설치 셸js
var shell = require('shelljs');
shell.mkdir('-p', fullPath);
해당 페이지에서:
사용 가능한 옵션:
p: 전체 경로(필요한 경우 중간 dir 생성)
다른 사람들이 지적했듯이, 더 집중적인 다른 모듈들이 있습니다.하지만 mkdirp 외에도 수많은 유용한 셸 작업(예: grep 등)이 있으며 창과 *nix에서 작동합니다.
편집: mkdir CLI 인스턴스가 없는 시스템에서는 이 기능이 작동하지 않습니다.그렇지 않습니다.이것이 포인트 셸js입니다. 셸과 같은 기능의 휴대용 크로스 플랫폼 세트를 만듭니다.그것은 심지어 창문에서도 작동합니다.
fs-module은 native 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
축소를 사용하면 각 경로가 존재하는지 확인하고 필요한 경우 생성할 수 있으며, 이 방법을 사용하는 것이 더 쉽다고 생각합니다.편집되었습니다. @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에서 node인 node.js를 것만큼 쉽습니다.{recursive: true}
두 로서.fs.mkdir()
공식 문서의 예를 참조하십시오.
외부 모듈이나 자체 구현이 필요하지 않습니다.
인 것은 nodejs v10.12.0과 으로 이 질문을 은 nodejs v10.12.0입니다.recursive
옵션이 true.fs.vmsdir로 설정됨
// 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 >= JS >=와 함께 .10.12.0
사용할 수 있습니다.fs.mkdirSync(path, { recursive: true })
fs.mkdirSync
Windows(추가 종속성 및 오류 처리 없음)의 예
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
폴더의 존재 여부를 반복적으로 확인하여 폴더가 존재하지 않는지 확인할 수 있습니다. (외부 라이브러리 없음)
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('/'));
}
});
}
다음 기능을 사용할 수 있습니다.
const recursiveUpload = (경로: 문자열) => {const paths = path.syslog/)
const fullPath = paths.reduce((accumulator, current) => {
fs.mkdirSync(accumulator)
return `${accumulator}/${current}`
})
fs.mkdirSync(fullPath)
return fullPath
}
그래서 그것이 하는 일은:
- 를 작성
paths
변수. 여기서 모든 경로를 배열의 요소로 저장합니다. - 배열의 각 요소 끝에 "/"를 추가합니다.
- 주기에 적합합니다.
- 인덱스가 0부터 현재 반복까지인 배열 요소의 연결로 디렉터리를 만듭니다.기본적으로, 그것은 재귀적입니다.
도움이 되길 바랍니다!
참고로 Node v10.12.0에서는 경로를 추가 인수로 지정하여 재귀 경로 생성을 사용할 수 있습니다.
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);
}
});
};
Windows 대 Linux 호환성에 관심이 있는 사용자는 위의 두 가지 경우 모두 슬래시를 이중 백슬래시 '\'로 바꾸기만 하면 됩니다. 하지만 TBH에서는 Windows 명령줄이 아닌 노드 fs에 대해 이야기하고 있으며 전자는 상당히 용서적이며 위의 코드는 Windows에서 간단히 작동하며 보다 완벽한 솔루션 크로스 플랫폼입니다.
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);
}
디렉터리를 재귀적으로 만드는 비동기식 방법:
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
nodejs용.
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);
}
}
상대 경로에 대해 작동합니다.
산악인의 의존성 제로 답변을 바탕으로, 여기 약간 더 초보자 친화적인 것이 있습니다.Typescript
변형, 모듈로:
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)
}
})
}
fs.mkdir의 재귀 옵션에 문제가 있어서 다음과 같은 기능을 만들었습니다.
- 최종 대상 dir로 시작하여 루트 상위 디렉터리까지 작업하는 모든 디렉터리 목록을 만듭니다.
- mkdir 함수가 작동하는 데 필요한 새 디렉터리 목록을 만듭니다.
최종 디렉터리를 포함하여 필요한 각 디렉터리를 만듭니다.
function createDirectoryIfNotExistsRecursive(dirname) { return new Promise((resolve, reject) => { const fs = require('fs'); var slash = '/'; // backward slashes for windows if(require('os').platform() === 'win32') { slash = '\\'; } // initialize directories with final directory var directories_backwards = [dirname]; var minimize_dir = dirname; while (minimize_dir = minimize_dir.substring(0, minimize_dir.lastIndexOf(slash))) { directories_backwards.push(minimize_dir); } var directories_needed = []; //stop on first directory found for(const d in directories_backwards) { if(!(fs.existsSync(directories_backwards[d]))) { directories_needed.push(directories_backwards[d]); } else { break; } } //no directories missing if(!directories_needed.length) { return resolve(); } // make all directories in ascending order var directories_forwards = directories_needed.reverse(); for(const d in directories_forwards) { fs.mkdirSync(directories_forwards[d]); } return resolve(); }); }
저는 다른 재귀적 답변과 유사한 방법으로 문제를 해결했지만 저에게는 이것이 훨씬 이해하고 읽기 쉽습니다.
const path = require('path');
const fs = require('fs');
function mkdirRecurse(inputPath) {
if (fs.existsSync(inputPath)) {
return;
}
const basePath = path.dirname(inputPath);
if (fs.existsSync(basePath)) {
fs.mkdirSync(inputPath);
}
mkdirRecurse(basePath);
}
필요한 권한으로 dir를 생성하는 예제를 찾을 수 없습니다.
원하는 사용 권한으로 비동기식으로 디렉터리를 만듭니다.
여기 일반적인 nodejs 솔루션이 있습니다.
노드 v18.12.1 Ubuntu 18
//-----------------------------
const fs = require('fs');
const fsPromises = fs.promises;
const checkDirAccess = async (userDir) => {
try {
await fsPromises.access(userDir, fs.constants.R_OK | fs.constants.W_OK);
console.log(` ${userDir} Dir existss`);
return userDir;
} catch (err) {
if(err.errno = -2)
return await crDir(userDir);
else
throw err;
}
}
const crDir = async (userDir) => {
try {
let newDir = await fsPromises.mkdir(userDir, { recursive: true, mode: 0o700});
// When userDir is created; newDir = undefined;
console.log(` Created new Dir ${newDir}`);
return newDir;
} catch (err) {
throw err;
}
}
const directoryPath = ['uploads/xvc/xvc/xvc/specs', 'uploads/testDir11', 'uploads/xsXa/', 'uploads//xsb//', 'uploads//xsV/'];
const findDir = async() => {
try {
for (const iterator of directoryPath) {
let dirOK = await checkDirAccess(iterator);
if(dirOK)
console.log(`found ${dirOK}`)
}
} catch (error) {
console.error('Error : ', error);
}
}
Exec은 창에서 지저분할 수 있습니다.더 많은 "노디" 해결책이 있습니다.기본적으로 디렉터리가 있는지 확인하고 디렉터리가 있는지 확인하거나 디렉터리가 있는지 확인하거나 디렉터리를 만듭니다.완료되면 자식을 만들고 함수를 호출하는 함수는 다음과 같습니다.
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();
}
})();
}
이 버전은 두 가지를 모두 이해하기 때문에 상위 답변보다 Windows에서 더 잘 작동합니다./
그리고.path.sep
따라서 Windows(윈도우)에서 필요한 대로 순방향 슬래시가 작동합니다. 경로 및 경로를 합니다(" " " " " " " " " " " " " " " " " " " " " " " "와 관련이 있습니다.process.cwd
).
/**
* Creates a folder and if necessary, parent folders also. Returns true
* if any folders were created. Understands both '/' and path.sep as
* path separators. Doesn't try to create folders that already exist,
* which could cause a permissions error. Gracefully handles the race
* condition if two processes are creating a folder. Throws on error.
* @param targetDir Name of folder to create
*/
export function mkdirSyncRecursive(targetDir) {
if (!fs.existsSync(targetDir)) {
for (var i = targetDir.length-2; i >= 0; i--) {
if (targetDir.charAt(i) == '/' || targetDir.charAt(i) == path.sep) {
mkdirSyncRecursive(targetDir.slice(0, i));
break;
}
}
try {
fs.mkdirSync(targetDir);
return true;
} catch (err) {
if (err.code !== 'EEXIST') throw err;
}
}
return false;
}
언급URL : https://stackoverflow.com/questions/31645738/how-to-create-full-path-with-nodes-fs-mkdirsync
'code' 카테고리의 다른 글
bash 스크립트에서 여러 프로그램을 병렬로 실행하려면 어떻게 해야 합니까? (0) | 2023.05.13 |
---|---|
패키지의 각 종속성을 업데이트하는 방법.최신 버전의 json? (0) | 2023.05.13 |
Postgre 버전SQL을 실행하고 있습니까? (0) | 2023.05.13 |
파일당 한 줄씩 재귀적인 전체 경로 목록을 얻으려면 어떻게 해야 합니까? (0) | 2023.05.13 |
SQL에서 조인 순서가 중요합니까? (0) | 2023.05.13 |