NodeJS 파일시스템에 관하여

🪐 C:on·2022년 2월 7일
0

자바스크립트

목록 보기
4/4


참고 : nodeJS교과서 by 조현영


🔎 fs 모듈

파일을 생성하거나 삭제하고, 읽거나 쓸 수 있으며 폴더를 만들었다 지웠다 할 수 있다.

const fs = require('fs');
fs.readFile('./readme.txt', (err, data) => {
  if (err) {
    throw err;
  }
  console.log(data);
  console.log(data.toString());
});

에러가 발생하지 않으면 그 다음코드인 console.log가 실행되며 콘솔에는 예기치 못한 Buffer가 출력될 것이다.

toString 메서드를 사용해보면 정상적으로 문자가 출력된다.

readfile의 결과는 버퍼 형식으로 제공되기 때문이다.


비동기

fs모듈의 readfile은 비동기로 동작한다.
함수가 동작되면 백그라운드에 파일읽기 명령을 요청하고 다음 작업으로 넘어간다.

읽기가 완료된 요청은 메인스레드에 알림을 주고 메인스레드는 그 때 콜백함수를 실행한다.

이 방식을 활용하면 수백개의 I/O요청에도 메인스레드는 요청처리만 위임하며 처리 완료 알림을 받았을 때만 콜백함수를 처리함으로써 많은 요청을 받아낼 수 있다.

동기와 비동기의 차이는 함수가 return 되는가이다.
블로킹과 논블로킹의 차이는 백그라운드 작업 완료 여부이다.


동기

readfile을 동기적으로 사용하기 위해서는 readfileSync를 사용해야 한다.

이 함수는 콜백함수를 넣는 대신에 return 값을 받아서 사용한다.

동기메서드를 사용하는 경우는 극히 드물며 비동기 메서드가 훨씬 효율적이기 때문에 웬만해선 비동기메서드를 사용한다.




🔎 버퍼와 스트림

노드는 파일을 읽을 때 메모리에 파일 크기만큼 공간을 마련해두며, 파일 데이터를 메모리에 저장한 뒤 사용자가 조작할 수 있도록 해준다.
여기서 메모리에 저장된 데이터를 버퍼라고 한다.


Buffer

버퍼 객체의 메서드

  • from(문자열): 문자열을 버퍼로 바꾼다.
    • .length : 버퍼의크기를 알려줍니다. 바이트 단위입니다.
  • toString(버퍼) : 버퍼를 다시 문자열로 변환
  • concat(배열): 배열 안에 든 버퍼들을 하나로 합침
  • alloc(바이트): 빈 버퍼를 생성, 바이트를 인자로 지정해주면 해당 크기의 버퍼가 생성된다

stream

readfile은 모든 내용을 버퍼에 다 쓴 후에야 다음 동작으로 넘어가므로 파일 읽기, 압축, 파일 쓰기 등의 조작을 연달아 할 때 매번 전체 용량을 버퍼로 처리해야 다음 단계로 넘어갈 수 있다.

때문에 버퍼의 크기를 작게 쪼개서 여러번 보내는 스트림 방식이 등장했다.

const fs = require('fs');
const readStream = fs.createReadStream('./readme3.txt', { highWaterMark: 16 });
const data = [];

readStream.on('data', (chunk) => {
  data.push(chunk);
  console.log('data :', chunk, chunk.length);
});

readStream.on('end', () => {
  console.log('end :', Buffer.concat(data).toString());
});

readStream.on('error', (err) => {
  console.log('error :', err);
});

createReadStream()은 읽기 스트림을 만들어준다.
첫번째 인자는 읽을 경로이며, 두번째 인자는 옵션 객체이다.
옵션 중 highWaterMark를 설정하여 버퍼의 크기를 정할 수 있다.

이벤트 리스너를 붙여서 사용한다. 대개 data, end, error를 사용한다.
읽기가 시작되면 data, 다 읽으면 end, 에러가 발생하면 error 이벤트가 발생한다.


pipe

파일을 읽는 스트림과 파일을 쓰는 스트림을 연결할 수 있는데 이를 파이핑이라하며 pipe 메서드를 사용해서 구현한다.

const fs = require('fs');
const readStream = fs.createReadStream('readme4.txt');
const writeStream = fs.createWriteStream('writeme3.txt');
readStream.pipe(writeStream);



🔎 fs 메서드

  • fs.mkdir(경로, 에러콜백) : 폴더를 만드는 메서드, 이미 폴더가 있다면에러가 발생하므로 먼저 존재 확인 메서드를 호출해서 확인 필요

  • fs.open(경로, 옵션, 콜백(에러, 아이디)) : 파일의 아이디를 가져오는 메서드, 파일이 없다면 파일을 생성한 뒤 그 아이디를 가져온다. 가져온 아이디를 사용해 fs.read()fs.write()로 읽거나 쓸 수 있다.
    두 번째 인자로 어떤 동작을 할 것인지 설정할 수 있습니다. 쓰려면 'w',읽으려면 'r', 기존 파일에 추가하려면 'a'이다.

  • fs.rename(기존 경로, 새 경로, 콜백) : 파일의 이름을 바꾸는 메서드입니다. 기존 파일 위치와 새로운 파일 위치를 적어준다. 파일을 이동할 때 활용된다.

  • fs.readdir(경로, 콜백(에러, 결과)) : 폴더 안의 내용물을 확인, 배열안에 내부 파일과 폴더명이 나온다.

  • fs.unlink(경로, 에러콜백) : 파일을 삭제. 파일이 없다면 에러가발생하므로 먼저 파일이 있는지를 꼭 확인한다.

  • fs.rmdir(경로, 에러콜백) : 폴더를 삭제. 폴더 안에 파일이 있다면 에러가 발생하므로 먼저 내부 파일을 모두 지우고 호출

0개의 댓글