82.0 실전예제: 파일 아카이브 구현하기

이번에는 C 언어로 파일 아카이브를 구현해보겠습니다. 파일 아카이브는 파일 안에 파일을 보관하는 방식을 뜻하며 매우 광범위하게 사용되고 있습니다.

다음은 대표적인 파일 아카이브 포맷입니다.

  • 압축 파일: zip, rar 등의 압축 포맷은 파일 안에 다른 파일을 압축하여 보관합니다.
  • 테이프 아카이브 파일: tar는 유닉스/리눅스 명령인데 여러 파일을 파일 하나로 묶어줍니다. 단, 압축은 하지 않습니다. 오래 전 자기 테이프를 쓰던 시절부터 있던 포맷이라 테이프 아카이브(tape archive)라 부릅니다.
  • 게임 데이터 파일: 파일 아카이브 포맷은 게임에서 주로 사용됩니다. 게임은 텍스처(그림 파일), 3D 모델, 사운드 파일, 애니메이션 파일, 각종 수치 데이터 등으로 이루어져 있는데 파일 개수가 보통 몇 백 개에서 많게는 수십만 개에 이르기도 합니다. 이렇게 많은 파일을 운영체제에 그대로 설치해서 게임을 실행하면 성능이 잘 나오지 않습니다. 왜냐하면 운영체제에서 파일을 열고, 읽는 작업은 생각보다 부하가 크기 때문입니다. 따라서 수많은 파일을 하나로 묶어서 아카이브 파일로 만들면 파일을 여는 동작은 한 번만 하면 되고, 이후부터는 파일 포인터를 이동시키면서 읽기만 하면 되기 때문에 성능이 향상됩니다.
    • MPQ: Mo'PaQ의 약자이며 블리자드에서 만든 게임에서 사용되는 파일 아카이브 포맷입니다. 최근에 나온 게임부터는 MPQ 포맷보다 유지보수, 성능, 확장성이 뛰어난 CASC(Content Addressable Storage Container) 포맷을 사용하고 있습니다.

zip, tar, MPQ와 같이 역사가 깊고 범용적으로 쓰이는 포맷을 그대로 구현하기는 쉽지가 않습니다. 이러한 포맷들은 다양한 요구사항을 만족해야 하고 성능도 뛰어나야 하기 때문에 구조가 복잡하고 여러 가지 최적화 방법이 들어가 있습니다. 따라서 이번 예제에서는 다음과 같은 기능을 간단한 방식으로 구현해보겠습니다.

  • 아카이브 파일에 새 파일 추가(append)
  • 아카이브 파일에 들어있는 파일의 목록 출력(list)
  • 아카이브 파일에 들어있는 파일을 추출하여 새 파일로 저장(extract)

참고로 이번 예제는 내용이 길고 복잡합니다. 특히 파일 처리 함수의 동작과 파일 포인터의 위치를 눈여겨 보는 것이 좋습니다.