fs.readFile(path,[options],callback)
참고 링크(Node.js)
https://nodejs.org/dist/latest-v16.x/docs/api/fs.html#fsreadfilepath-options-callback
File system | Node.js v16.19.0 Documentation
nodejs.org
1. 설명
비동기적으로 파일의 전체 내용을 읽는다.
Asynchronously reads the entire contents of a file.
fs.readFile()은 전체 파일을 버퍼링한다. 메모리 cost를 최소화하려면 가능한 fs.createReadStream()으로 스트리밍 하는 것을 선호한다.
The fs.readFile() function buffers the entire file. To minimize memory costs, when possible prefer streaming via fs.createReadStream().
진행 중인 요청을 중단하는 것은 개별 OS 요청을 중단하는 것이 아니라 fs.readFile의 내부적인 버퍼링을 수행하는 것이다.
Aborting an ongoing request does not abort individual operating system requests but rather the internal buffering fs.readFile performs.
2. 매개변수(parameter)
1) path
- 설명 : 읽고 싶은 파일의 파일명 또는 filedescripter
- 타입 : <string> | <buffer> | <URL> | <integer>
- path가 폴더(directroy)일 경우 platform에 따라 다르게 동작한다.
macOS, Linux, Window일 경우 에러가 리턴되고, FreeBSD인 경우 directory의 내용이 리턴된다.
const fs = require('fs');
// platform이 macOS, Linux, Windows인 경우
fs.readFile(디렉토리명, (err, data) => {
if(err) throw err;
console.log(data); // illegal operation on a directory
})
// platform이 FreeBSD인 경우
readFile(디렉토리명, (err, data) => {
// => null, <data>
});
2) options(선택적)
- 설명 : 인코딩 방식, file flag, signal을 설정
- 타입 : <Object> | <string>
◦ encoding : <string> | <null> (Default : null)
◦ flag : <string> (Default : 'r')
◦ signal : <AbortSignal> (처리중인 readFile을 중단한다.)
- encoding 방식을 별도로 지정하지 않는다면 raw buffer가 리턴된다.
- [예시] options의 type이 Object 또는 string일 경우
const fs = require('fs');
// 1. options의 type이 Object일 때
let options = {encoding : 'utf-8', flag: 'r'};
fs.readFile('path', options, (err, data) => {
// ...
});
// 2. options의 type이 string일 때
fs.readFile('path', "utf-8", (err, data) => {
// ...
});
- 진행중인 요청(request)을 중단하고 싶다면 AbortSignal을 사용한다.
요청(request)이 중단되면 AbortError와 함께 callback이 호출된다.
const fs = require('fs');
const controller = new AbortController();
const signal = controller.signal;
fs.readFile('파일명', {signal}, (err, data) => {
// ...
});
// 요청을 중단하고 싶을 때 사용한다.
controller.abort();
3) callback
- 설명 : 파일을 읽은 후 비동기적으로 실행되는 함수
- 타입 : <Function>
- 매개변수
◦ err : <Error> | <AggregateError>
◦ data : <string> | <buffer> (파일의 내용)
// Node.js에서 fs 모듈을 사용할 때 아래와 같은 코드를 작성하여 fs 모듈을 불러온다.
const fs = require('fs');
fs.readFile('/etc/passwd', (err, data) => {
if(err) throw err;
console.log(data);
})
4. 성능 고려 사항
Performance Considerations
fs.readFile() 메서드는 메모리로 한 번에 한 chunk씩 파일의 내용을 읽고, event loop가 각 chunk 사이로 전환하게 한다.
The fs.readFile() method asynchronously reads the contents of a file into memory one chunk at a time, allowing the event loop to turn between each chunk.
이것은 읽기 작업(read operation)이 다른 작업(기본적으로 libuv thread pool을 사용하는 작업)에서 영향이 작게 하지만, 메모리에서 파일을 완전히 읽는데 오래 걸린다는 것을 의미한다.
This allows the read operation to have less impact on other activity that may be using the underlying libuv thread pool
but means that it will take longer to read a complete file into memory.
추가적인 read overhead는 각 시스템에서 크게 다르고, 읽고 있는 파일의 유형에 따라 다르다.
The additional read overhead can vary broadly on different systems and depends on the type of file being read.
파일 유형이 일반적이지 않고(예 : pipe) Node.js가 실제 파일의 크기를 결정하기 어렵다면 각 읽기 작업(read operation)은 64KiB로 로드된다. 일반적인 파일의 경우 각각 512KiB로 읽기 처리한다.
If the file type is not a regular file (a pipe for instance) and Node.js is unable to determine an actual file size, each read operation will load on 64 KiB of data. For regular files, each read will process 512 KiB of data.
가능한 파일 내용을 빨리 읽어야하는 application의 경우, fs.read()를 직접 사용하고, application 코드 자체가 전체적인 내용을 읽는 것을 관리하게 하는 것이 좋다.
For applications that require as-fast-as-possible reading of file contents, it is better to use fs.read() directly and for application code to manage reading the full contents of the file itself.
Node.js의 GitHub issue #25741은 다양한 Node.js 버전에서 여러 파일의 사이즈의 fs.readFile()의 성능에 대해 더 많은 정보와 자세한 분석을 제공한다.
The Node.js GitHub issue #25741 provides more information and a detailed analysis on the performance of fs.readFile() for multiple file sizes in different Node.js versions.