[node.js] Node.js를 사용하여 디렉토리가 존재하지 않는 경우 디렉토리를 작성하는 방법은 무엇입니까?

디렉토리가없는 경우이를 작성하는 올바른 방법입니까? 스크립트에 대한 모든 권한이 있어야하며 다른 사람이 읽을 수 있어야합니다.

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);
}


답변

아니요, 여러 가지 이유가 있습니다.

  1. path모듈은 없습니다 exists/ existsSync방법. 그것은에있는 fs모듈. (아마도 질문에 오타가 있었습니까?)

  2. 문서는 명시 적으로 권장하지 않습니다 사용에서 당신을 exists.

    fs.exists()은 시대 주의적이며 역사적 이유로 만 존재합니다. 자신의 코드에서 사용할 이유가 거의 없습니다.

    다른 프로세스가 호출 사이의 파일을 제거 할 수있다 : 특히, 파일을 열기 전에 존재하는 경우는 잎 당신이 취약 경쟁 조건에 대한 안티 패턴 확인 fs.exists()하고 fs.open(). 파일을 열고없는 경우 오류를 처리하십시오.

    우리는 파일이 아닌 디렉토리에 대해 이야기하고 있기 때문에이 조언은 무조건 호출 mkdir하고 무시 해야 함을 의미합니다 EEXIST.

  3. 일반적으로 * 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


답변

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를 사용하여 디렉토리를 만들 때 더 읽기 쉬운 동기식 방식으로 파일 작성을 활용함으로써 더 멋진 모습을 원할 것입니다. 그러나 그것은 질문의 범위를 벗어납니다.


답변

한 줄 버전에 관심이있는 사람을 위해. 🙂

//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
    })

(선택적으로 모드와 함께 두 번째 인수를 추가하십시오.)


다른 생각들:

  1. 그런 다음 네이티브 약속 을 사용하여 기다리거나 기다릴 수 있습니다 .

    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() })
  2. 당신은 (unested)와 같은 자신의 약속 방법을 만들 수 있습니다 :

    let mkdirAsync = (path, mode) => new Promise(
       (resolve, reject) => mkdir (path, mode,
          err => (err && err.code !== 'EEXIST') ? reject(err) : resolve()
          )
       )
  3. 동기 검사의 경우 다음을 사용할 수 있습니다.

    fs.existsSync(path) || fs.mkdirSync(path)
  4. 또는 가장 인기있는 두 가지 라이브러리 인 라이브러리를 사용할 수 있습니다.

    • mkdirp (폴더 만 수행)
    • fsextra (슈퍼 셋 fs, 많은 유용한 것들을 추가합니다)

답변

으로 FS-추가 패키지 당신이 할 수있는 한 라이너 :

const fs = require('fs-extra');

const dir = '/tmp/this/path/does/not/exist';
fs.ensureDirSync(dir);