✨ Lecture 1 : 파일 시스템
시스템 API는 라이브러리 함수와 다르다는 점을 알아야 한다. 라이브러리 함수는 제조사에서 편리하게 사용자들이 이용하도록 만든 툴이다. 시스템 API는 운영체제를 베이스로 해서 만들어진 함수들이다. 제조사마다 시스템 API를 다르게 사용해 라이브러리를 만든다.
파일이란?
파일은 정보의 논리적 저장 단위이다. 운영체제는 FCB (File Control Block)을 유지하여 파일에 대한 정보를 저장한다.
운영체제에서 파일 시스템 제공
파일 시스템은 파일의 물리적 의미, 구조, 속성, 연산을 정의한다. 또한 논리적 파일을 물리적 보조 저장 장치에 매핑하는 알고리즘과 자료구조 등을 제공한다. 파일 시스템은 기본적으로 계층적 구조로 이루어져 있다. 파일의 Core - Child 가 존재하는 식으로, 족보처럼 쭉 연결되어 있다.
다양한 파일 시스템들이 있는데, 사용자는 시스템 콜을 이용해서 다양한 저장장치에 파일을 저장할 수 있다. 다양한 파일 시스템들은 VFS 로 매핑되어서 유저는 다양한 파일 시스템에 대해 고려하지 않고 시스템 인터페이스를 사용할 수 있다.
유닉스 파일 시스템 구조
디스크 드라이브상에 여러개의 Partition 들이 있다. 파티션 위에는 File System 이 있는데, 파일 시스템은 실린더 그룹별로 나뉜다. 실린더 그룹 안에는 super 블록부터 시작해서 inode 블럭, 데이터 블럭들이 존재한다.
inode 블럭에 파일에 대한 정보들이 존재한다.
유닉스의 큰 특징중에 하나는 file table 을 inode table 이라 한다는 것이다. 파일은 아이노드의 집합이다.
temp 라는 파일에 위와 같이 정보를 저장해서 ls -l 을 하여 정보들을 확인하면, 여러 메타데이터를 가진 파일이 만들어 졌음을 확인할 수 있다. 이 파일에 대한 정보는 inode table 에 저장되어 있다. 실제 데이터 값들은 데이터 블록에 들어가 있고, inode table 에서 포인터를 타고 들어가 접근할 수 있다.
inode 가 같으면 동일한 파일이다. mv 와 cp 를 했을 때의 inode 의 차이를 보면 알 수 있다.
슈퍼 블록 정보 보기 : df
디렉토리
유닉스에서 디렉토리도 파일처럼 취급된다.
디렉토리는 아이노드 번호와 파일명으로 구성된 목록 파일이다.
항상 . (자기 자신) 과 .. (부모 디렉토리)를 포함한다.
ls -l 파일 을 하면 가상 파일 시스템을 거쳐서, 실제 파일 시스템에 접근하고, 해당 파일에 대한 정보를 유저에게 던져주게 된다.
어떤 과정을 통해서 ls 가 작동하는지 알아보자.
아이노드를 갖고, 아이노드 저장소를 확인한다. 저장된 위치를 확인해 물리저장소 위치를 찾아낸다. 찾은 후 데이터를 터미널에 뿌려준다. 들어있는 파일들에 대해서 이 과정을 반복하며 모든 파일들의 리스트를 디스플레이 한다.
파일은 File Descriptor 와 Read Write Pointer 를 이용해 컨트롤 한다.
파일 디스크립터, 파일 기술자
파일 기술자는 실행중인 프로그램이 관리하는 (프로세스가 관리하는) 파일객체들의 포인터 배열에 대한 인덱스이다. 음수가 아닌 정수값으로 이 값은 시스템(커널)이 결정하며, 파일 오픈에 실패하면 -1을 반환한다. 여러개의 프로그램이 동시에 하나의 파일을 개발할 수 있다.
파일 기술자의 0,1,2 번은 표준 입력, 출력, 에러로 지정되어 있다. 표준 입출력과 에러는 정해진 파일 기술자를 이용해서 이루어진다.
파일을 개방한 후에는 읽고 쓰는 작업을 해야한다. 읽고 쓸 때 작업을 수행할 바이트 단위의 위치를 찾아야 한다. 파일을 개방한 직후에 읽기/쓰기 포인터는 0이다. 파일의 첫 번째 바이트를 가리키는 것이다. 파일의 내용을 읽거나, 새로운 데이터를 작성하면 그만큼 증가한다.
두 개의 프로세스가 하나의 파일에 대해서 작업을 수행할 수 있다. 파일에는 read write pointer 가 존재하고, 해당 포인터를 이용해서 파일을 읽거나 파일에다가 쓸 위치를 지정할 수 있다. Read Only 이므로 여러 프로세스가 동시에 읽을 수 있다. 읽어온 내용은 버퍼에 저장이 된다.
✨ Lecture 2 : 파일의 기본 동작
*** [ ] 안에 있는 것은 생략 가능한 매개변수
Open 함수
물론 플래그를 사용해서 새로운 파일을 생성한 후 개방할 수 도 있다. 에러 체크를 프로그래머가 해주어야 한다는 점에 주의하자.
* O_EXCL
* O_TRUNC
Creat 함수
Close 함수
Read Write
ssize_t 는 int 값
read 가 정상적으로 수행되면 fd 를 통해 BUFSZIE 만큼을 읽어서 buf 에다가 저장한다.
ssize_t 변수를 두어서 사이즈를 확인함으로써 정상적으로 쓰여졌는지 확인한다.
읽는 곳과 쓰는 곳의 위치를 변경하는 lseek.
어떤 파일을, 어디서부터 읽을건지 지정한다. whence 는 SEEK_SET, SEEK_CUR, SEEK_END 로 오프셋의 기준이다.
파일의 맨 처음부터 읽었을 때 3으로 갔다가, -2 하면 1번으로 이동하고, 뒤에서부터 0번째를 지정하면 가장 끝으고 가고, 다시 그 위치로부터 -3 하면 6번으로 간다.
주의 : 디렉터리를 삭제할 때는 rmdir 를 사용한다. unlink 는 파일을 삭제할때만 사용한다.
실습 : 다음과 같이 data.txt 파일을 만들어서 읽고, 출력하는 것을 해보자.
소스코드
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(void){
int fd, fd1, fd2;
ssize_t nread;
off_t newpos;
char buffer[1024];
char content[] = "Hello!\n";
fd = open("data.txt", O_RDWR);
nread = read(fd, buffer, 1024);
write(1, buffer, nread);
write(fd, content, 7);
newpos = lseek(fd, (off_t)5, SEEK_SET);
nread = read(fd, buffer, 1024);
write(1, buffer, nread);
close(fd);
fd1 = open("data1.txt", O_RDWR | O_CREAT, 644);
fd2 = creat("data2.txt", 644);
close(fd1);
close(fd2);
unlink("data2.txt");
return 0;
}
출력 결과
'Linux Programming Basics' 카테고리의 다른 글
Shell 사용하기 (0) | 2020.07.03 |
---|---|
[Linux Programming] Process Related API (0) | 2020.06.30 |
Linux : File Management Commands (0) | 2020.06.28 |
Linux : Command Environment (0) | 2020.06.28 |
Linux : History and Characteristics (0) | 2020.06.28 |