노드가 존재하지 않는 경우 디렉토리를 작성하는 방법은 무엇입니까?
디렉토리가없는 경우이를 작성하는 올바른 방법입니까? 스크립트에 대한 모든 권한이 있어야하며 다른 사람이 읽을 수 있어야합니다.
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()
. 파일을 열고없는 경우 오류를 처리하십시오.우리는 파일이 아닌 디렉토리에 대해 이야기하고 있기 때문에이 조언은 무조건 호출
mkdir
하고 무시 해야 함을 의미합니다EEXIST
.일반적으로 *
Sync
메소드 는 피해야합니다 . 차단 중이므로 디스크로 이동하는 동안 프로그램에서 다른 어떤 것도 발생할 수 없습니다. 이것은 매우 비용이 많이 드는 작업이며 시간이 걸리면 노드의 이벤트 루프에 대한 핵심 가정이 깨집니다.*
Sync
메소드는 일반적으로 단일 목적의 빠른 스크립트 (한 가지 작업을 수행 한 다음 종료되는 스크립트)에서는 훌륭하지만 서버를 작성할 때는 거의 사용하지 않아야합니다. 서버는 전체 기간 동안 누군가에게 응답 할 수 없습니다. I / O 요청 중 여러 클라이언트 요청에 I / O 작업이 필요한 경우 서버가 매우 빨리 중단됩니다.
내가 * 사용을 고려 줄 유일한 시간
Sync
서버 응용 프로그램에서 방법은 일어나는 동작에 한 번 시작할 때, (한 번만). 예를 들어require
실제로readFileSync
모듈을로드 하는 데 사용합니다.그럼에도 불구하고 많은 동기 I / O가 불필요하게 서버의 시작 시간을 느리게 할 수 있기 때문에 여전히주의해야합니다.
대신 비동기 I / O 방법을 사용해야합니다.
그래서 우리가 그 조언들을 정리하면, 우리는 다음과 같은 것을 얻습니다 :
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 모듈을 발견했다. "mkdir -p"와 같이 필요할 때 재귀 적으로 mkdir을 수행합니다.
https://www.npmjs.com/package/mkdirp
한 줄 버전에 관심이있는 사람을 위해. :)
//or in typescript: import * as fs from 'fs';
const fs = require('fs');
!fs.existsSync(dir) && fs.mkdirSync(dir);
mkdir
폴더가 존재하면 오류를 사용 하고 잡을 수 있습니다 .
이것은 비동기 적이므로 최상의 방법입니다.
fs.mkdir('/path', err => {
if (err && err.code != 'EEXIST') throw 'up'
.. safely do your stuff here
})
(선택적으로 모드와 함께 두 번째 인수를 추가하십시오.)
다른 생각들:
그런 다음 네이티브 약속 을 사용하여 기다리거나 기다릴 수 있습니다 .
const util = require('util'), fs = require('fs'); const mkdir = util.promisify(fs.mkdir); var myFunc = () => { ..do something.. } mkdir('/path') .then(myFunc) .catch(err => { if (err.code != 'EEXIST') throw err; myFunc() })
당신은 (unested)와 같은 자신의 약속 방법을 만들 수 있습니다 :
let mkdirAsync = (path, mode) => new Promise( (resolve, reject) => mkdir (path, mode, err => (err && err.code !== 'EEXIST') ? reject(err) : resolve() ) )
동기 검사의 경우 다음을 사용할 수 있습니다.
fs.existsSync(path) || fs.mkdirSync(path)
또는 가장 인기있는 두 가지 라이브러리 인 라이브러리를 사용할 수 있습니다.
이 mkdir
메소드는 존재하지 않는 경로에 디렉토리 를 재귀 적으로 작성 하고 존재하는 디렉토리는 무시할 수 있습니다.
로부터 노드 V10 / 11 문서 :
// Creates /tmp/a/apple, regardless of whether `/tmp` and /tmp/a exist.
fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
if (err) throw err;
});
참고 : 내장 fs
모듈을 먼저 가져와야합니다 .
다음은 네이티브 ES 모듈 (플래그 활성화 및 .mjs 확장명 사용)을 활용하고 루트가 아닌 경로를 처리하며 전체 경로 이름을 설명하는 좀 더 강력한 예입니다.
import fs from 'fs';
import path from 'path';
createDirectories(pathname) {
const __dirname = path.resolve();
pathname = pathname.replace(/^\.*\/|\/?[^\/]+\.[a-z]+|\/$/g, ''); // Remove leading directory markers, and remove ending /file-name.extension
fs.mkdir(path.resolve(__dirname, pathname), { recursive: true }, e => {
if (e) {
console.error(e);
} else {
console.log('Success');
}
});
}
처럼 사용할 수 있습니다 createDirectories('/components/widget/widget.js');
.
물론 async / await와 함께 promise를 사용하여 디렉토리를 만들 때 더 읽기 쉬운 동기식 방식으로 파일 작성을 활용함으로써 더 멋진 모습을 원할 것입니다. 그러나 그것은 질문의 범위를 벗어납니다.
가장 좋은 해결책은 node-fs-extra 라는 npm 모듈을 사용하는 것 입니다. mkdir
언급 한 디렉토리를 만드는 메소드가 있습니다. 긴 디렉토리 경로를 지정하면 상위 폴더가 자동으로 생성됩니다. 이 모듈은 수퍼 npm 모듈 세트이므로이 모듈 을 추가해도 fs
모든 기능을 사용할 수 있습니다 fs
.
으로 FS-추가 패키지 당신이 할 수있는 한 라이너 :
const fs = require('fs-extra');
const dir = '/tmp/this/path/does/not/exist';
fs.ensureDirSync(dir);
var dir = 'path/to/dir';
try {
fs.mkdirSync(dir);
} catch(e) {
if (e.code ~= 'EEXIST') throw e;
}
var filessystem = require('fs');
var dir = './path/subpath/';
if (!filessystem.existsSync(dir)){
filessystem.mkdirSync(dir);
}else
{
console.log("Directory already exist");
}
이것은 당신을 도울 수 있습니다 :)
josh3736 's answer의 Typescript Promise 리 팩터를 추가하고 싶습니다 .
똑같은 일을하고 같은 경우가 있습니다. 약속을 사용하고 typescript typedef를 사용하고 "엄격한 사용"으로 작동합니다.
// 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
}
});
});
}
다음은 디렉토리를 반복적으로 작성하는 작은 기능입니다.
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
}, '')
}
다음 예제와 같이 node File System 명령 fs.stat 를 사용하여 dir이 있는지 확인하고 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);
}
});
};
async / await 사용 :
const mkdirP = async (directory) => {
try {
return await fs.mkdirAsync(directory);
} catch (error) {
if (error.code != 'EEXIST') {
throw e;
}
}
};
약속해야합니다 fs
:
import nodeFs from 'fs';
import bluebird from 'bluebird';
const fs = bluebird.promisifyAll(nodeFs);
중요 : 해당 파일이나 디렉토리가 없습니다. mkdir './assets/
해결책
// const fs = require('fs') in javascript
// import * as fs from "fs" in typescript
// import fs from "fs" in typescript
!fs.existsSync(`./assets/`) && fs.mkdirSync(`./assets/`, { recursive: true })
참고 URL : https://stackoverflow.com/questions/21194934/node-how-to-create-a-directory-if-doesnt-exist
'Programming' 카테고리의 다른 글
Javascript의 문자열에서 해시 생성 (0) | 2020.02.11 |
---|---|
파이썬이 사전에 새로운 아이템 추가 (0) | 2020.02.11 |
고정 이름이 'System.Data.SqlClient'인 ADO.NET 제공자에 대한 Entity Framework 제공자를 찾을 수 없습니다. (0) | 2020.02.11 |
이 앱의 개발자가 Facebook 로그인을 위해이 앱을 올바르게 설정하지 않았습니까? (0) | 2020.02.11 |
IntelliJ 편집기에서 무제한 공백을 끄려면 어떻게합니까? (0) | 2020.02.10 |