File
유닉스에서 파일의 특징에는 다음과 같은 것들이 있다.
A container of data : 데이터를 포함하는 컨테이너
File is a contiguous sequence of bytes : 연속된 바이트의 서열
No format imposed by the operating system : OS가 정한 파일의 형태가 특정되지 않음
Each byte is individually addressable in a disk file : 모든 바이트는 디스크 파일에서 주소 지정 가능
File is also a uniform interface to external devices : 외부 장치의 인터페이스들 조차 파일로 간주
Filesystem
파일 시스템
컴퓨터 파일과 데이터를 정리하고 저장하는 방법
파일에 접근하기 쉽다.
파일 시스템은 데이터 저장장치(하드디스크, CD-ROM)를 사용할 수 있다.
File System Interface란 System call을 말한다. 기본적으로는 (open, create, close, read, write, lseek, unlink, remove, fcntl)가 있다.
유저 프로그램(User app)이 system call을 부르기 위해서 trap(s/w interrupt)을 발생시키면, File System Management, Hardware Control을 통해서 Hardware 장치로 전달된다.
이때 Disk와 같은 block 장치인지, 키보드와 같은 character 장치인지에 따라 적절한 디바이스 드라이버를 이용하여 Hardware Control로 진행된다. character의 경우 입출력 한 단위가 1byte이지만, block의 경우 1block이 4KB이기에 buffer cache가 필요하다.
위 함수들은 표준화된 C가 아닌 POSIX.1과 XPG3 즉 UNIX 표준에 포함되어있다.
또한 라이브러리에는 버퍼가 없다. (커널 버퍼를 말하는 것이 아님)
File Descriptor
커널에서 파일을 열 때, 지정하는 번호를 말한다. 이때 지정되는 번호는 음수가 아닌 정수들이다.
파일을 새로 만들거나 기존의 파일을 열 때, 즉 open이나 create명령어를 사용할 때 커널이 file descriptor를 반환해준다.
file descriptor를 read나 write로 넘겨주어 해당 파일에 대한 read와 write를 진행할 수 있다.
유닉스에서 process를 만들면 기본적으로 다음과 같은 세 개의 file descriptor가 할당된다.
File descriptor | Symbolic constant | describe |
0 | STDIN_FILENO | Standard input |
1 | STDOUT_FILENO | Standard output |
2 | STDERR_FILENO | Standard error |
0번은 표준입력이다. (컴퓨터에서는 사용자의 표준입력이 키보드인 셈이다) 1번과 2번은 표준 출력 즉 스크린으로 출력함을 의미하는데 정상적인 출력이냐 에러출력이냐를 구분한다.
위 0,1,2의 file descriptor가 생성시 할당되므로, open 명령어를 통해 파일을 처음 열면 '3'번이 나온다. 사용되지 않는 음이 아닌 정수 중 가장 작은수를 반환하는 것이다.
예제코드
/* a rudimentary example program */
/* these header files are discussed below */
#include <fcntl.h>
#include <unistd.h>
main()
{
int fd; // file descriptor
ssize_t nread;
char buf[1024];
/* open file “data” for reading */
fd = open(“data”, O_RDONLY);
// 위 "data"라는 파일에 해당하는 경로는 상대경로로 현재경로인 working directory
// O_RDONLY 는 open_mode로 read only를 의미
/* read in the data */
nread = read(fd, buf, 1024);
// fd 파일의 1024byte를 읽어 buf에 담는다.
/* close the file */
close(fd);
}
처음으로 open을 통해 파일을 열면 fd에는 0,1,2,는 생성이 할당이 이미 되었으므로 3이 반환된다. 이 번호가 "data"라는 이름의 파일을 지정하는 번호이다.
이 번호(fd)를 가지고 read를 한다. read명령어를 실행할 때 파일의 크기가 1024만큼 되지 않고 예를들어 100byte라고 한다면, 100byte만큼만을 읽어오고 읽어온 byte수를 nread로 반환한다.
close를 통해 파일을 닫는다.
헤더에 대해서 알아보자
혹시나 헤더의 <>에 대해서 설명하자면, /usr/include/헤더파일명 을 의미한다. 즉 "/usr/include"가 default 디렉토리인 셈이다.
fcntl.h 헤더는 open 시스템 콜이 선언되어있고, unistd.h 헤더에는 ssize_t 자료형이 포함되어있다. ssize_t는 int인데 typedef로 이름만 바꾸어 놓은 것이다. 자료형을 따로 설정한 이유는 read의 반환값으로 받는 값의 자료형이 시스템마다 short, long 등 다양하기 때문에 표준화한 것이다. (ssize_t가 unistd.h에 포함되어있고, sys/types.h헤더는 unistd.h를 포함한다)
예를들어 다른 환경에서는 sys 헤더에 ssize_t 자료형이 int가 아니라 short로 처리되어있고, 그걸 ssize_t 자료형을 통해 표준화하여 쓰는 것이다.
환경별로 다른 자료형을 충돌없이 숨기기 위해서 sys/types.h의 typedef로 선언된 자료형을 사용하는 것이다.
'개발 · 컴퓨터공학' 카테고리의 다른 글
Real Time Rendering 4th Edition 번역 공부 - Ch.1_1.2 (mathematical notation) (0) | 2021.09.15 |
---|---|
UNIX system call - open (0) | 2021.09.14 |
네트워크 프로그래밍 - TCP 소켓 프로그래밍의 시작 (0) | 2021.09.12 |
네트워크 프로그래밍 - TCP란? (0) | 2021.09.07 |
UNIX의 구조와 기본적인 개념들 (0) | 2021.09.05 |