File
파일은 데이터를 장기 저장하는 저장 공간으로, 다음과 같은 특징을 갖는다.
1. 많은 양의 데이터를 저장할 수 있다.
2. 저장된 데이터는 그 데이터를 사용한 프로세스가 종료되어도 남아있는다.
3. 여러 프로세스가 동시에 데이터에 접근할 수 있다.
다음은 다양한 파일 확장자들의 예시를 보여준다.
이중에서 gif는 무손실 압축을 지향하는 이미지 확장자이고, JPG는 압축률을 높이는 대신 어느 정도 손실을 감수하는 확장자이다.
파일의 내부 구조는 크게 위와 같이 3가지 종류가 있을 수 있다.
(a)는 byte sequence 형태로 데이터를 저장한 것을 말한다.
윈도우, UNIX와 같은 운영체제에서 이 방식을 지원한다.
(b)는 Record Sequence 형태로 데이터를 저장한 형태이다.
이때 레코드의 크기는 모두 고정된 크기를 가지며, 예전에 주로 사용한 방식이다.
(c)는 트리 형태로 데이터를 저장하는 방법이다.
트리는 레코드에 대한 트리이며, 이때 (b)와 달리 레코드의 크기가 같지 않아도 괜찮다.
그림에서는 레코드의 key 필드만 보여주고 있는데, key 필드는 하나의 레코드를 유일하게 식별할 수 있는 필드이다.
이때 데이터는 사전순으로 정렬되어 있어 만약 양(lamb)을 찾고 싶다면 L 은 F와 P 사이이므로 Fox 와 Pig 사이의 화살표를 타고 내려간 뒤, G와 L 사이의 필드를 타고 내려가서 Lamb를 찾는다.
(데이터베이스의 B+ 트리와 비슷하다. 오히려 디비에서 배운 내용과 많이 겹친다. DB에서도 레코드 단위로 저장하기 때문이다.)
File Type
UNIX 시스템에는 다음과 같이 4가지 종류의 파일이 존재한다.
1. regular file
- ASCII File : 우리가 흔히 다루는 문자열 데이터로 구성된 파일. 라인 끝마다 \r 과 \n 과 같은 문자가 들어있다.
- Binary File : ASCII File 이외의 파일을 말한다.
바이너리 파일에는 대표적으로 Executable File 과 archive file이 존재한다.
2. directory
파일을 모아서 보관하는 하나의 폴더
디렉토리 자체도 하나의 파일이며, 어떤 서브 디렉토리가 어떤 파일을 갖고 있는지와 같은 정보도 함께 저장한다.
따라서 디렉토리는 system file 이기도 하다.
3. Character Special File
Serial Device를 모델링한 파일이다. Serial Device는 마우스, 네트워크, 프린터, 터미널(키보드)과 같이 연속된 데이터에 대해 I/O를 수행하는 디바이스를 말한다. 즉, 유닉스에서는 마우스를 움직이거나 네트워크를 통해 데이터를 받으면 Serial 데이터를 받는데 이 데이터들을 Character Special File 의 형태로 받는다.
4. Block Special File
디스크를 모델링한 파일이다. 하나의 디스크가 여러 개의 블록으로 이루어져 있고, 이 각각의 블록을 파일의 형태로 모델링해서 관리한다.
위 그림은 Regular File 중 Binary File에 속하는 파일의 구조를 보여준다.
(a)는 그 중에서 executable file의 구조를 보여준다.
executable file은 소스코드를 컴파일해서 나오는 그 실행파일을 말한다.
이 파일의 헤더에는 Magic Number 필드가 존재하는데, 이 필드에는 이 file이 executable file임을 나타내는 identify 값이 들어간다. 예를 들어 매직 넘버 값이 77일 때 executable file 이라면, 운영체제가 어떤 파일을 프로그램으로서 실행할 때는 매직넘버를 확인하여 이 값이 77인지 사전에 확인하고 77이면 실행하는 방법으로 동작한다.
그 내용에는 Text 부분에 실제 소스코드가 들어있고, 어디부터 실행해야 할 지 그 위치는 Header의 Entry Point를 통해 알 수 있다.
(b)는 아카이브 파일의 구조를 보여준다.
아카이브 파일은 일종의 라이브러리(프로시저의 모임)와 같다.
위 그림에서는 (header - object module) 의 조합이 3개가 붙어있는, 3개의 라이브러리 프로시저 (라이브러리 모듈) 로 구성되어 있음을 알 수 있다.
아카이브 파일의 모든 라이브러리 프로시저는 기계어로 번역이 되어있는 상태이다.
File Access
과거 파일에 접근할 때는 Sequencial Access 방법을 사용했다.
물리적으로 파일의 데이터는 마그네틱 테이프에 저장되어 있었으며, 그 특성상 데이터를 읽을 때는 앞에서부터 쭉 차례대로 읽었기 때문이다.
이 방법은 파일 속 데이터를 읽을 때 반드시 순차적으로 연속해서 읽어야 하므로 jump를 한다거나 하는 일은 수행할 수 없다.
대신 되감거나(rewind) back-up 하는 기능은 수행할 수 있었다.
최근에는 디스크의 등장으로 Random Access 방법을 주로 사용한다.
이 방법은 바이트/레코드를 어디든지 순서에 상관없이 점프해서 읽을 수 있고, DB 시스템에 필수적인 파일 접근 방법이다.
이 방법을 사용할 때는 현재 파일의 어디를 읽고 있는지를 나타내는 file marker가 존재하며, 이 marker가 가리키는 곳에 대해 read, write를 진행한다. (당연히 데이터를 읽을 때마다 marker의 위치는 그 옆으로 이동한다.)
File Attribute
파일에는 다양한 속성들이 존재한다.
Protection은 이 파일에 접근 권한이 있는 유저만 접근하도록 보호하는 것을 말한다.
(유닉스에서 chmod를 통해 설정할 수 있는 유저 권한, 그룹 권한 등의 정보가 이곳에 저장된다.)
Hidden Flag를 설정하면 숨김파일이 되어 디스플레이에는 파일이 보이지 않는다.
(ls 명령어를 통해 현재 디렉토리의 모든 파일을 볼 수 있다. 이때 -a 옵션을 주면 히든 파일도 함께 보여준다.)
ASCII / Binary Flag는 이 파일이 regular file 중에서 어떤 종류의 파일인지 나타내는데 사용된다.
Key Position 속성은 각 레코드에 대해 키의 위치를 오프셋 값으로 저장하는 속성이다.
이런 속성은 위에서 살펴본 다양한 파일의 구조 중 레코드로 구성된 파일 구조에서 사용하는 속성이다.
File Operations
파일과 관련된 시스템 콜
Create / Delete / Open / Close
파일 속성, 파일이 위치한 디스크 블록 주소 등을 메모리로 불러오면 inode 라는 공간에 저장하고, file descriptor 라는 테이블에 inode 주소를 저장하고 있는 entry를 저장한다. Create / Open 명령어는 이 entry의 인덱스를 반환하며 Read / Write 할 때 이를 통해 파일에 접근하여 조작을 가한다.
Read / Write / Append
Seek
Get Attribute / Set Attribute
Rename
파일에 접근해서 데이터를 읽고 쓸 때, 매번 read, write 버퍼와 파일 포인터를 준비해서 복잡하게 하기 보다,
세그멘테이션 시스템을 사용하는 경우, 파일 자체를 하나의 별도 세그먼트로 올려서 관리할 수도 있다.
이렇게 하면 파일에 접근해서 데이터를 읽거나 쓸 때 마치 메모리 배열에 접근하듯 편하게 사용할 수 있다고 한다. (참고)
Directory
윈도우의 폴더와 유사한 개념의 파일
예전의 디렉토리는 Single-Level Directory 로, Root directory 밑에 모든 파일이 존재했다.
위 그림에서 동그라미는 파일을 의미하고, 라벨은 이 파일을 만든 유저를 말한다.
따라서 이 그림은 root directory에는 A유저의 파일 2개와 B, C 유저의 파일 1개가 각각 있는 상태를 보여준다.
지금과 같은 상태에서는 각 유저들의 파일이 한 공간에 모두 있다보니 관리에 불편함이 존재한다.
그래서 이렇게 각각의 유저마다 User directory를 두고, 그 밑에 각 유저가 생성한 파일을 관리하는 two-level directory가 등장했다.
하지만 이때까지만 해도 이 이상의 서브 디렉토리는 만들 수 없었기에 불편함이 남아있었다.
그래서 최종적으로는 이렇게 루트 디렉토리 밑에 각 유저 별 디렉토리를 두고, 그 밑에서 자유롭게 서브 디렉토리와 파일을 저장할 수 있는 계층 구조가 되었다.
유닉스 시스템의 파일 구조는 이렇게 되어있다.
이때 각각의 파일과 디렉토리의 위치를 표시하기 위해 path 라는 개념이 등장했다.
path 를 표현할 때는 절대경로(absolute path)와 상대경로(relative path)가 존재한다.
절대 경로는 파일의 위치를 항상 최상단의 root 디렉토리를 기준으로 표현하는 것
상대 경로는 파일의 위치를 현재 위치한 디렉토리를 기준으로 표현하는 것을 말한다.
(working directory 또는 current directory 라고도 부른다.)
root 디렉토리의 경로는 / 이다.
위 그림에서 root directory 밑에는 bin, etc, lib, usr, tmp 와 같은 서브 디렉토리가 존재한다.
이들 각각의 경로는 /bin, /etc, /lib, /usr, /tmp 와 같이 절대경로로 나타낼 수 있다.
만약 현재 위치하는 곳이 / 라면, bin, etc 와 같이 바로 디렉토리 이름을 작성해서 상대 경로를 작성할 수 있다.
그래서 위 그림에서 jim 이라는 폴더의 절대 경로가 /usr/jim 으로 표현된 것을 볼 수 있다.
Directory Operation
파일 시스템과 마찬가지로 디렉토리와 관련된 조작 역시 시스템 콜에 의해 실행된다.
디렉토리는 그 자체로 역시 파일이며, 그 내부적으로는 디렉토리에 포함된 파일들의 정보가 리스트(테이블)로 들어있다.
- Create / Delete
디렉토리를 생성하면 기본적으로 그 정보 안에 . 과 .. 라는 2개 엔트리가 기본적으로 리스트에 들어있다.
이때 . 은 현재 디렉토리를 의미하고, .. 은 부모 디렉토리를 가리킨다.
- Opendir / Closedir / Readdir
디렉토리라는 파일을 읽을 때도 역시 Open, Close, Read 관련 시스템콜을 호출한다.
Readdir 는 디렉토리 내부의 엔트리들에 대해 그 다음 엔트리를 반환한다.
이 시스템 콜을 통해 디렉토리 내부의 모든 레귤러 파일과 서브 디렉토리 정보를 읽을 수 있다.
- Rename / Link / Unlink
unlink는 디렉토리 내 엔트리를 삭제하는 것과 같으며, 이는 곧 파일을 삭제하는 것과 같다.
(엔트리가 사라지면 파일의 위치를 표현할 방법이 없으니 접근할 수 없어지기 때문이다.)
자세한 내용은 파일 시스템 구현에 대한 글에서 정리한다.
'CS > 운영체제' 카테고리의 다른 글
[운영체제] 20. UNIX V7 File System (0) | 2024.12.08 |
---|---|
[운영체제] 19. 파일 시스템 구현 (0) | 2024.12.08 |
[운영체제] 17. Segmentation (0) | 2024.12.05 |
[운영체제] 16. 페이지 교체 알고리즘 (0) | 2024.12.05 |
[운영체제] 15. 메모리 관리 (4) | 2024.12.03 |