Random Access File은 파일 시스템에서 임의의 위치에 직접 접근하여 데이터를 읽거나 쓰는 방식입니다. 일반적인 순차적 파일 접근(sequential file access)과 달리, 파일 내 특정 위치로 바로 이동하여 데이터를 처리하는 것을 말합니다
Random Access File
1. 성능 최적화
순차적으로 파일을 처음부터 끝까지 읽을 필요 없이, 필요한 데이터가 있는 위치로 바로 이동하여 빠르게 접근할 수 있습니다. 예를 들어, 아주 큰 파일에서 특정 부분만 자주 읽거나 수정해야 하는 경우, 파일의 처음부터 끝까지 모두 읽는 것보다 특정 위치에 직접 접근하는 것이 훨씬 빠르고 효율적입니다.
- 예시: 대용량 로그 파일에서 마지막 몇 줄만 읽고 싶을 때, 파일의 처음부터 읽는 것이 아니라 파일 끝으로 바로 가서 읽으면 속도가 훨씬 빨라집니다.
2. 데이터 수정
순차 접근에서는 파일의 처음부터 끝까지 데이터를 읽거나 새로 작성해야 하지만, 랜덤 접근을 사용하면 파일의 특정 부분만 수정할 수 있습니다. 이는 특히 대용량 파일을 다룰 때 유용합니다.
- 예시: 데이터베이스 파일에서 특정 레코드만 수정할 때, 수정할 레코드의 위치로 이동하여 필요한 부분만 변경할 수 있습니다.
3. 파일 내 특정 구조 접근
일부 파일 포맷은 내부에 구조화된 데이터(예: 인덱스, 메타데이터)를 가지고 있습니다. 이런 구조에서 필요한 데이터가 파일의 특정 위치에 있을 수 있으므로, 그 부분만 읽기 위해 랜덤 액세스를 사용합니다.
- 예시: 이미지 파일의 헤더 정보나 동영상 파일의 특정 메타데이터를 읽을 때, 파일의 전체 내용을 읽지 않고 해당 위치로 바로 접근하여 필요한 데이터를 처리할 수 있습니다.
4. 데이터베이스와 유사한 파일 구조
랜덤 파일 접근은 데이터베이스 파일이나 B-Tree 구조와 같은 시스템에서 필수적입니다. 이런 시스템에서는 특정 데이터가 항상 파일의 고정된 위치에 저장되기 때문에, 해당 위치로 바로 이동해 데이터를 읽거나 수정하는 방식으로 최적의 성능을 제공합니다.
- 예시: 관계형 데이터베이스 시스템에서 데이터는 특정 위치에 인덱싱되어 저장되며, 데이터를 수정하거나 읽을 때 순차 접근보다 랜덤 접근이 훨씬 빠릅니다.
5. 대규모 파일 처리
순차적으로 데이터를 처리하면 시간과 메모리 자원이 많이 소모되는데, 랜덤 액세스를 통해 파일의 작은 부분만 읽고 쓸 수 있으면 메모리 사용량을 줄일 수 있습니다.
- 예시: 비디오 편집 소프트웨어에서 대형 동영상 파일의 특정 부분만 편집할 때, 파일 전체를 읽지 않고 필요한 부분만 랜덤하게 접근합니다.
Random File Access의 단점:
- 복잡한 구현: 순차적인 파일 접근보다 구현이 복잡할 수 있습니다. 파일 내에서 특정 위치로 이동하거나 데이터를 업데이트하는 논리가 더 복잡합니다.
- 디스크 I/O 성능 저하: 하드디스크(HDD)처럼 물리적인 디스크에서 랜덤 액세스를 많이 하면 디스크 헤드가 여러 위치로 이동해야 하므로 성능이 저하될 수 있습니다. 하지만 SSD와 같은 저장 장치에서는 랜덤 액세스의 성능 저하가 크지 않습니다.
- 데이터 구조의 의존성: 파일의 구조를 이해하고 있어야만 정확한 위치로 이동할 수 있기 때문에, 사용자가 파일 형식에 대해 명확하게 알고 있어야 합니다.
fs/promise를 사용한 예제 코드
import promiseFs from 'node:fs/promises'
export const FileBuffer = async (path: string) => {
//파일 핸들 생성 - 지정된 경로의 파일을 읽기 모드('r')로 엽니다.
const fileHandle = await promiseFs.open(path, 'r')
// slice 메서드 - 파일의 특정 부분을 읽어오는 기능을 합니다.
// 지정된 크기만큼의 버퍼를 생성하고 파일에서 데이터를 읽어옵니다
const slice = async (start: number, end: number) => { // start: 읽기 시작할 위치, end: 읽기를 끝낼 위치
const chunkSize = end - start
const buffer = Buffer.alloc(chunkSize)
await fileHandle.read(buffer, 0, chunkSize, start)
return buffer.buffer
}
// close 메서드 - 파일 핸들을 닫는 기능을 합니다. 메모리 누수를 방지하기 위해 사용이 끝난 후 반드시 호출해야 합니다
const close = async () => {
await fileHandle.close()
}
return {
slice,
close,
}
}
이 함수는 Random Access로 파일의 일부분을 읽어오는 버퍼 기능을 제공하는 유틸리티 함수입니다. 주로 대용량 파일을 처리할 때 유용하며, 전체 파일을 한 번에 메모리에 로드하지 않고 필요한 부분만 읽어올 수 있게 해줍니다. 특히 미디어 파일과 같은 큰 파일을 스트리밍하거나 부분적으로 처리할 때 효율적입니다.
참고: https://2ality.com/2022/06/nodejs-file-system.html
https://nodejs.org/api/fs.html#class-filehandle
https://reakwon.tistory.com/165