Javascript/Typescript

[Node.js] fs 모듈로 파일 입출력 처리

범데이 2022. 9. 28. 01:29

1. 개요

fs 모듈은 FileSystem의 약자로 파일 처리와 관련된 모듈이다. 메소드가 굉장히 많은데 가장 중요하고 기초적인 내용 위주로 살펴보자.

 

 

 

2. fs 모듈 불러오기

fs 모듈은 Node.js에 내장되어 있기 때문에 별도의 라이브러리 설치 없이 바로 불러와서 사용할 수 있다.

 

CommonJS모듈 시스템을 사용하는 프로젝트에서는 require 키워드로 불러오고, ES모듈 시스템을 사용하는 프로젝트에서는 import 키워드를 사용 할 수 있다.

// CommonJS Modules
const fs = require("fs");

// ES Modules
import fs from "fs";

 

 

 

3. fs 모듈의 비동기 함수 vs 동기 함수

fs 모듈은 비동기(asynchronous) API와 동기(synchronous) API를 모두 제공하고 있다. 따라서 본인이 작성하는 프로그램의 성격을 고려하여 둘 중에 어떤 API가 적합한지 판단해야 한다.

 

fs 모듈에서 제공하는 비동기 메서드는 마지막 인자로 콜백(callback) 함수를 받고 아무 값도 반환하지 않는다. 반면에 fs모듈에서 제공하는 동기 메서드는 결과값을 반환(return)하며 예외(exception)을 일으킬 수 있다. 동기 메서드의 이름은 Sync로 끝나기 때문에 쉽게 비동기 메서드인지 동기 메서드인지 구분이 가능하다.

 

 

 

4. fs모듈의 주요 메서드

(1) 디렉토리 생성

비동기로 디렉토리를 만들 때는 mkdir() 메서드를 사용한다.

예를 들어, "testDir" 라는 디렉토리를 생성하는 코드를 작성하면, 다음과 같다.

fs.mkdir("testDir", (err) => console.log(err));

 

동일한 작업을 동기 버전으로 사용하려면, mkdirSync() 메서드를 사용해서 구현할 수 있다.

try {
  fs.mkdirSync("testDir");
} catch (err) {
  console.log(err);
}

 

 

 

(2) 디렉토리 삭제

비동기로 디렉토리를 삭제할 때는 rmdir() 메서드를 사용한다.

예를 들어, 방금 생성한 "testDir"라는 디렉토리를 삭제하는 코드는 다음과 같다.

fs.rmdir("testDir", (err) => console.log(err));

 

 

동일한 작업을 동기 버전으로 사용하려면, rmdirSync() 메서드를 사용해서 구현할 수도 있다.

try {
  fs.rmdirSync("testDir");
} catch (err) {
  console.log(err);
}

 

 

(3) 파일에 데이터 쓰기

fs모듈은 비동기로 파일에 데이터를 쓸 수 있도록 writeFile() 메서드를 제공하고 있다.

예를 들어, test.txt라는 파일에 "fasd"라는 문자열을 쓰는 코드를 작성해보자.

 const fileName = "test.txt";
 const text = "fasd";
 fs.writeFile(fileName, text, (err) => console.log(err));

 

동일한 작업을 동기 버전으로 사용하려면, writeFileSync() 메서드를 사용해서 구현 가능하다.

try {
  const fileName = "test.txt";
  const text = "fasd";
  fs.writeFileSync(fileName, text);
} catch (err) {
  console.log(err);
}

 

 

주의할 점은 writeFile() 메서드를 사용하면 기존에 파일에 있던 데이터를 덮어쓴다. 기존에 파일에 있던 데이터 뒤에 새로운 데이터를 추가하고 싶다면 해당 메서드 대신에 appendFile() 또는 appendFileSync() 와 같은 메서드를 사용해야 한다.

 

 

 

(4) 파일로부터 데이터 읽기

fs 모듈의 readFile() 메서드를 사용하면 비동기로 파일의 데이터를 읽을 수 있다.

fs.readFile("test.txt", "utf8", (err, data) => {
  if (err) {
    console.error(err);
  } else {
    console.log(data);
  }
});

 

주의할 점은 반드시 두번째 인자를 "utf8" 와 같이 명시하여 인코딩이 되도록 해줘야 한다. 두번째 인자를 생략하면 콜백 함수의 data 인자로 문자열이 아닌 버퍼(buffer) 데이터가 넘어온다.

 

동일한 작업을 동기 버전으로 사용하려면, readFileSync() 메서드를 사용해서 구현할 수 있다.

try {
  const data = fs.readFileSync("test.txt", "utf8");
  console.log(data);
} catch (err) {
  console.log(err);
}

 

 

 

(5) 파일/디렉토리의 메타 정보 확인하기

stat() 함수는 파일이나 디렉토리의 메타 정보를 확인할 때 사용한다.

 

예를 들어, 위에서 생성한 test.txt 파일에 대한 메타 정보를 출력하는 코드를 작성하면 다음과 같다.

fs.stat("test.txt", (err< stats) => {
  if (err) {
    console.error(err);
  } else {
    console.log({
      size: stat.size,
      mtime: stats.mtime,
      isFile: stats.isFile(),
    });
  }
});

콜백 함수의 두번째 인자로 넘어오는 stats객체를 통해 해당 파일이나 디렉토리에 대한 다양한 메타 정보에 접근할 수 있다. 예제 코드에서는 파일 크기(size)와 수정 시간(mtime), 그리고 파일인지 디렉토리인지 반환하는 isFile() 메서드를 호출했다.

 

마찬가지로 동기 버전으로 사용하려면, statSync() 메서드를 사용해서 동일한 작업을 구현할 수 있다.

try {
  const stats = fs.statSync("test.txt");
  console.log({
    size: stats.size,
    mtime: stats.mtime,
    isFile: stats.isFile(),
  });
} catch (err) {
  console.error(err);
}

 

 

위 코드를 터미널에서 실행하면 다음과 같이 파일의 메타 정보가 출력될 것이다.

{ size: 18, mtime: 2022-09-27T15:08:16.596Z, isFile: true }

 

 

 

5. 실제 사용 코드

(1) 사용사례A

아래는 buffer형태의 영상 데이터를 fs 모듈을 사용해 파일로 떨구는 실제 사용 코드를 발췌한 것이다.

  ...
  const webmVideoName = `myVideo.webm`;
  const buffer = Buffer.from(videoBufferData);

  fs.writeFile(webmVideoName, buffer, (err: any) => {
    err ? console.error(err) : console.log(`${webmVideoName} write successed!`);
    
    ...
  })

fs모듈을 사용하는 코드를 살펴보면 간단하다.

 

 파일 이름과 파일에 쓸 데이터를 인자로 넘겨주어, 결과를 받아 반환된 error data가 있으면 console.error() 함수로 해당 에러를 출력하고, error data가 없으면 파일이 잘 쓰여졌다고 console.log() 메서드로 출력한다.

 

 

 

 

(2) 사용사례B

아래는 mp4형태의 영상 데이터를 fs 모듈을 사용해 읽어들여서, Blob형태로 변환한 코드를 발췌한 것이다.

const fileNameMp4 = "myVideo.mp4";

fs.readFile(fileNameMp4, (err: any, data: any) => {
  if (err) {
    console.error(`read video failure! file: ${fileNameMp4}`, err);
    return;
  } else {
    console.log(`read video successed! file: ${fileNameMp4}`);

    const blobMp4 = new Blob([data], {
      type: "video/mp4",
    });
    
    ...
  }
});

마찬가지로 fs모듈을 사용하는 코드를 살펴보면 간단하다.

 

 파일 이름을 인자로 넘겨주어 파일을 읽고, 콜백으로 결과를 받아 반환된 error data가 있으면 console.error() 함수로 해당 에러를 출력한 뒤 메서드를 리턴하고, error data가 없으면 파일이 잘 읽혔다고 console.log() 메서드로 출력한 뒤, 읽은 파일의 데이터를 사용하게 된다.

 

 


#References

https://opentutorials.org/module/938/7373

https://nodejs.org/api/fs.html

https://www.daleseo.com/js-node-fs/

반응형