이 블로그에 파일 입출력에 대한 개념이 잘 정리되어 있다.
리눅스에서 파일을 읽고 쓰는 방법은 저수준 파일입출력과 고수준 파일입출력으로 구분할 수 있다. 각각의 차이는 다음 표와 같고, 나는 파일 디스크럽터를 통해 파일을 다룰 수있는 가장 기본적인 OPEN, READ함수를 사용하기 위해 글을 정리해 보았다.
리눅스에서 파일을 읽고 쓰기 위해서는 반드시 파일을 Open 해야만 한다. 파일이 오픈되고 나면 파일 디스크립터라는 일종의 Index 번호가 반환되며, 이 값은 파일을 오픈한 프로세스의 고유 번호라 생각하면 이해하기 쉬울 것이다. 파일 디스크립터는 C int 타입으로 표현되며, 최대값은 1,024이지만 1,048,576번까지 설정할 수 있다. 또한, 프로세스마다 관례적으로 0,1,2번은 사전 배정되어 있는데 각각 번호별 의미는 다음과 같다.
0
: 표준 입력 (stdin)
1
: 표준 출력 (stdout)
2
: 표준 오류 (stderr)
따라서 실제 하나의 파일을 생성하게 되면 “3번” 부터 File Descriptor가 부여된다.
int open(const char *pathname, int flag, mode_t mode);
pathname : 파일의 경로와 이름이다. 절대경로의 파일명을 주어도 되고 상대경로의 파일명을 주어도 된다.
flags : 파일을 어떻게 열지를 결정한다. 읽기 전용으로 열때는 O_RDONLY
, 쓰기 전용으로 열때는 O_WRONLY
, 읽기 쓰기로 열고 싶을때는 O_RDWR
을 사용한다. 여러개의 flag들을 사용하고 싶을때는 | (OR) 연산을 사용한다.
예를 들어 읽기 쓰기 모드로 열고 싶은데 파일이 없으면 생성하는 flag는 O_RDWR | O_CREAT
로 사용하면 된다.
mode : 파일을 생성할때의 권한을 주는 옵션. 만약 0777을 주게 된다면 모두 읽기, 쓰기, 실행 권한을 주게 되는 것이다. 또한 가독성을 높이기 위해 심볼릭 상수도 제공한다. 심볼릭 상수를 사용할때 역시 | 연산으로 권한을 줄 수 있다.
반환값 : 성공적으로 파일을 열게되면 파일 디스크립터를 반환 한다. 그렇지 않으면 음수를 반환. 파일 사용이 끝나면 close()함수를 통해 파일을 닫아주어야 한다.
ssize_t read(int fd, void* buf, size_t len);
>> “fd가 바라보고 있는 파일에서 len길이 만큼을 buf에 읽어 들인다”