본문 바로가기

Library/File Structure

A Journey of a Byte

어떤 파일을 읽어들였다고 하자. 실제로 어떤 일이 일어날까? C/C++와 같은 고급 언어에서는 물리적인 파일을 은유하는 논리적인 개체를 돌려주고, 사용자는 이 개체를 이용해서 작업을 한다. 마치 메모리에 전체 파일이 올려져 있는 것처럼 자유롭게 파일을 다루지만, 운영체제의 입장에서는 사용자가 보는 것처럼 파일 전체를 메모리에 올려두는 것이 아니다. 그것은 전적으로 운영체제의 IO 시스템이 구현하고 있는 버퍼의 상황에 달려있다.

IO 버퍼는 단일 버퍼 형태로 구현될 수도 있으며, 풀링 형태로 구현될 수도 있다. 예를 들어, 사용자가 어떤 파일을 열고 이 파일의 끝에 'p'를 쓰려고 한다. 그렇다면 운영체제는 어떤 일을 하는가? 먼저, 운영체제는 그 파일이 메모리의 IO 버퍼에 존재하는지 확인하고, 존재하지 않는다면 그 부분을 읽어들여 해당 부분을 IO 버퍼에 올려둔다. 어떤 데이터를 버퍼에 읽어들여야 하는지 판단하는 것은 운영체제가 구현하고 있는 파일 시스템에 의존한다. 즉, 요청된 데이터의 실제 물리적인 위치를 알고 있는 것은 파일 시스템이며, 필요한 데이터를 적절하게 메모리에 올리는 일 또한 파일 시스템의 구현에 따라 달라진다. 중요한 것은 파일 전체가 메모리에 올려져 있을 수도 있지만, 데이터가 선택적으로 IO 버퍼에 올려져 있을 수도 있다는 점이다.

버퍼가 준비되었다면, 운영체제는 해당 버퍼에 위치한 데이터의 끝부분에 'p'를 올릴 것이다. 그리고, 이 버퍼가 언제 매체에 물리적으로 장될 것인지 결정한다. 사용자가 버퍼를 직접 쓰도록 명령할 수도 있고, 운영체제의 스케쥴링에 따라 선택될 수도 있다.

이런 IO 버퍼를 이용한 구현은, 메모리 한계를 넘는 크기의 파일을 읽어들일 수 있으며, 사용 가능한 메모리 크기보다 더 큰 여러 파일들을 동시에 읽는 것을 가능하게 한다.


Reference
Michael J. Folk, Bill Zoellick, Greg Riccardi, File Structure, Adison Wesley