참고 : nodeJS교과서 by 조현영
파일을 생성하거나 삭제하고, 읽거나 쓸 수 있으며 폴더를 만들었다 지웠다 할 수 있다.
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 값을 받아서 사용한다.
동기메서드를 사용하는 경우는 극히 드물며 비동기 메서드가 훨씬 효율적이기 때문에 웬만해선 비동기메서드를 사용한다.
노드는 파일을 읽을 때 메모리에 파일 크기만큼 공간을 마련해두며, 파일 데이터를 메모리에 저장한 뒤 사용자가 조작할 수 있도록 해준다.
여기서 메모리에 저장된 데이터를 버퍼라고 한다.
버퍼 객체의 메서드
from(문자열)
: 문자열을 버퍼로 바꾼다. .length
: 버퍼의크기를 알려줍니다. 바이트 단위입니다.toString(버퍼)
: 버퍼를 다시 문자열로 변환concat(배열)
: 배열 안에 든 버퍼들을 하나로 합침alloc(바이트)
: 빈 버퍼를 생성, 바이트를 인자로 지정해주면 해당 크기의 버퍼가 생성된다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
메서드를 사용해서 구현한다.
const fs = require('fs');
const readStream = fs.createReadStream('readme4.txt');
const writeStream = fs.createWriteStream('writeme3.txt');
readStream.pipe(writeStream);
fs.mkdir(경로, 에러콜백)
: 폴더를 만드는 메서드, 이미 폴더가 있다면에러가 발생하므로 먼저 존재 확인 메서드를 호출해서 확인 필요
fs.open(경로, 옵션, 콜백(에러, 아이디))
: 파일의 아이디를 가져오는 메서드, 파일이 없다면 파일을 생성한 뒤 그 아이디를 가져온다. 가져온 아이디를 사용해 fs.read()
나 fs.write()
로 읽거나 쓸 수 있다.
두 번째 인자로 어떤 동작을 할 것인지 설정할 수 있습니다. 쓰려면 'w'
,읽으려면 'r'
, 기존 파일에 추가하려면 'a'
이다.
fs.rename(기존 경로, 새 경로, 콜백)
: 파일의 이름을 바꾸는 메서드입니다. 기존 파일 위치와 새로운 파일 위치를 적어준다. 파일을 이동할 때 활용된다.
fs.readdir(경로, 콜백(에러, 결과))
: 폴더 안의 내용물을 확인, 배열안에 내부 파일과 폴더명이 나온다.
fs.unlink(경로, 에러콜백)
: 파일을 삭제. 파일이 없다면 에러가발생하므로 먼저 파일이 있는지를 꼭 확인한다.
fs.rmdir(경로, 에러콜백)
: 폴더를 삭제. 폴더 안에 파일이 있다면 에러가 발생하므로 먼저 내부 파일을 모두 지우고 호출