IT이야기

Node.js에 없는 경우에만 파일 생성

cyworld 2021. 9. 30. 21:55
반응형

Node.js에 없는 경우에만 파일 생성


파일에 쓰고 싶은 버퍼가 있습니다. 파일이 이미 존재하는 경우 해당 파일에 대한 색인을 증가시키고 다시 시도해야 합니다. 파일이 존재하지 않는 경우에만 생성하는 방법이 있습니까? 아니면 이미 존재하지 않는 파일을 찾는 오류가 발생할 때까지 파일을 통계화해야 합니까?

예를 들어, 나는 파일 a_1.jpga_2.jpg. 내 방법을 사용하여 a_1.jpga_2.jpg, 그리고 실패하고 마침내 성공적으로 a_3.jpg.

이상적인 방법은 다음과 같습니다.

fs.writeFile(path, data, { overwrite: false }, function (err) {
  if (err) throw err;
  console.log('It\'s saved!');
});

또는 다음과 같이:

fs.createWriteStream(path, { overwrite: false });

노드의 fs라이브러리 에 이와 같은 것이 있습니까?

편집 : 내 질문은 존재를 확인하는 별도의 기능이 있는지 여부가 아닙니다. 단일 파일 시스템 호출에서 파일이 존재하지 않는 경우 생성하는 방법이 있습니까?


당신의 직관이 올바르게 추측했듯이 한 쌍의 exists / writeFile호출을 사용한 순진한 솔루션 은 잘못되었습니다. 비동기 코드는 예측할 수 없는 방식으로 실행됩니다. 그리고 주어진 경우에는

  • 파일이 a.txt있습니까? - 아니요.
  • (파일 a.txt은 다른 프로그램에서 생성됨)
  • a.txt가능한 경우 작성 하십시오. - 괜찮아.

하지만 네, 우리는 한 번의 호출로 그것을 할 수 있습니다. 우리는 파일 시스템으로 작업하고 있으므로 에서 개발자 매뉴얼을 읽는 것이 좋습니다 fs. 그리고 여기 흥미로운 부분이 있습니다.

'w' - 쓰기 위해 파일을 엽니다. 파일이 생성되거나(존재하지 않는 경우) 잘립니다(존재하는 경우).

'wx' - 'w'와 비슷하지만 경로가 있으면 실패합니다.

따라서 호출에 추가 wx하기 만 하면 됩니다 fs.open. 하지만 이봐, 우리는 fopen같은 IO를 좋아하지 않습니다 . fs.writeFile조금 더 읽어봅시다 .

fs.readFile(파일명[, 옵션], 콜백)#

파일 이름 문자열

옵션 개체

인코딩 문자열 | 널 기본값 = 널

플래그 문자열 기본값 = 'r'

콜백 함수

그것은 options.flag유망 보인다. 그래서 우리는 시도

fs.writeFile(path, data, { flag: 'wx' }, function (err) {
    if (err) throw err;
    console.log("It's saved!");
});

그리고 그것은 단일 쓰기에 완벽하게 작동합니다. 이 코드로 작업을 해결하려고 하면 이 코드가 좀 더 기이한 방식으로 실패할 것이라고 생각합니다. 원자적으로 " a_#.jpg존재를 확인하고 비어 있으면 거기에 씁니다" 작업이 있지만 다른 모든 fs상태는 잠겨 있지 않으며 a_1.jpg이미 확인하는 동안 파일이 자발적으로 사라질 수 있습니다 a_5.jpg. 대부분의 * 파일 시스템은 ACID 데이터베이스 가 아니며 최소한 몇 가지 원자적 작업을 수행할 수 있다는 사실은 기적입니다. wx코드가 일부 플랫폼에서 작동하지 않을 가능성이 매우 높습니다 . 따라서 제정신을 위해 데이터베이스를 사용 하십시오 .

고통에 대한 몇 가지 추가 정보

memoize-fs네트워크/CPU 시간을 절약하기 위해 파일 시스템에 대한 함수 호출 결과를 캐시하는 것과 같은 것을 작성한다고 상상해 보십시오 . 파일이 있으면 읽기 위해 열 수 있고 없으면 쓰기 위해 파일을 열 수 있습니까? 모두 한 번의 호출로 가능합니까? 저 깃발들을 우스꽝스럽게 살펴보자. 우리가 볼 수있는 정신 운동의 잠시 후 a+우리가 원하는 것을 : 파일이 존재하지 않는 경우, 그것은 하나를 만들고, 읽기, 쓰기 위해 모두를 열고,이 같은 (파일을 삭제하지 않고 그렇게 파일이있는 경우 w+겠습니까 ). 그러나 이제 우리는 그것을 함수 (smth)File에서도 사용할 수 없습니다 create(Smth)Stream. 그리고 그것은 누락된 기능처럼 보입니다.

따라서 Node.js github에 기능 요청(또는 버그)으로 자유롭게 제출하십시오. 원자성 비동기 파일 시스템 API가 없다는 것이 Node.js의 단점이기 때문입니다. 비록 기대하지 않습니다 곧 변경 언제든지.


a옵션을 사용하는 것은 어떻습니까?

문서 에 따르면 :

'a+' - 읽고 추가하기 위해 파일을 엽니다. 파일이 없으면 생성됩니다.

와 완벽하게 작동하는 것 같습니다 createWriteStream


이 방법은 더 이상 권장되지 않습니다. fs.exists는 더 이상 사용되지 않습니다. 댓글을 참조하세요.

다음은 몇 가지 옵션입니다.

1) 2개의 "fs" 호출이 있습니다. 첫 번째는 " fs.exists " 호출이고 두 번째는 " fs.write / read 등"입니다.

//checks if the file exists. 
//If it does, it just calls back.
//If it doesn't, then the file is created.
function checkForFile(fileName,callback)
{
    fs.exists(fileName, function (exists) {
        if(exists)
        {
            callback();
        }else
        {
            fs.writeFile(fileName, {flag: 'wx'}, function (err, data) 
            { 
                callback();
            })
        }
    });
}

function writeToFile()
{
    checkForFile("file.dat",function()
    {
       //It is now safe to write/read to file.dat
       fs.readFile("file.dat", function (err,data) 
       {
          //do stuff
       });
    });
}

2) 또는 먼저 빈 파일을 만듭니다 .

--- 동기화:

//If you want to force the file to be empty then you want to use the 'w' flag:

var fd = fs.openSync(filepath, 'w');

//That will truncate the file if it exists and create it if it doesn't.

//Wrap it in an fs.closeSync call if you don't need the file descriptor it returns.

fs.closeSync(fs.openSync(filepath, 'w'));

--- 비동기:

var fs = require("fs");
fs.open(path, "wx", function (err, fd) {
    // handle error
    fs.close(fd, function (err) {
        // handle error
    });
});

3) 또는 " 터치 "를 사용 하십시오 : https://github.com/isaacs/node-touch


단일 시스템 호출에서 이를 수행하려면 fs-extranpm 모듈을 사용할 수 있습니다 . 그 후에 파일이 생성될 디렉토리와 함께 생성됩니다.

const fs = require('fs-extra');
const file = '/tmp/this/path/does/not/exist/file.txt'
fs.ensureFile(file, err => {
    console.log(err) // => null
});

또 다른 방법은 동일한 작업을 수행하지만 동기식인 sureFileSync 를 사용 하는 것입니다.

const fs = require('fs-extra');
const file = '/tmp/this/path/does/not/exist/file.txt'
fs.ensureFileSync(file)

다음과 같이 할 수 있습니다.

function writeFile(i){
    var i = i || 0;
    var fileName = 'a_' + i + '.jpg';
    fs.exists(fileName, function (exists) {
        if(exists){
            writeFile(++i);
        } else {
            fs.writeFile(fileName);
        }
    });
}

ReferenceURL : https://stackoverflow.com/questions/12899061/creating-a-file-only-if-it-doesnt-exist-in-node-js

반응형