[시스템 프로그래밍] Low-level File IO(1) - Open, Close
파일 입출력 방법은 Low-Level File IO (System call)와 High-Level File IO (Buddered IO)로 나뉩니다.
High-Level File IO는 File pointer를 사용하는 반면, Low-Level File IO는 File descriptor를 사용하여 입출력합니다.
이번 포스팅에서는 Low-Level File IO에 대해 알아보겠습니다.
1. File open and close
1-1 Open
$ man -s 2 open
man 명령어를 통해 open을 살펴보면 위와 같은 내용을 확인할 수 있습니다.
우선 "open"이라는 System call을 사용하기 위해서는 위에 보이는 세 가지의 헤더파일을 include해야 하는 것을 알 수 있습니다.
다음으로 open의 parameter를 살펴보도록 하겠습니다.
int open(const char *path, int oflag, /* mode_t mode */)
path : 파일의 이름을 포함한 파일의 경로
flags : 파일을 여는 방법(access mode) 설정
mode(optional) : 파일을 생성할 때만 사용하며 O_CREATE 인자를 사용
( /* */ 로 표기되어 있는 것은 optional하게 사용하는 것 입니다.
return값은 integer인데 file descriptor를 return하게 됩니다.
- File descriptor(fd, 파일 기술자)?
열려있는 파일을 구분하는 정수값으로 특수 파일 등 대부분의 파일을 지칭할 수 있다. 파일을 열 때 순차적으로 할당되며 Process당 최대 1024개의 fd를 관리할 수 있다.
Default로 정해져있는 fds는 0, 1, 2 세가지 입니다.
0 : stdin, 표준 입력
1 : stdout, 표준 출력
2 : stderr, 표준 오류
- Flags
O_RDONLY : (ReaD ONLY) 파일을 읽기 전용으로 연다.
O_WRONLY : (WRite ONLY) 파일을 쓰기 전용으로 연다.
O_RDWR : (ReaD WRite) 파일을 읽기와 쓰기가 가능하게 연다.
O_CREAT : 파일이 없으면 파일을 생성한다.
O_EXCL : O_CREAT 옵션과 같이 사용할 경우 기존에 없는 파일이면 파일을 생성하고, 이미 있다면 에러메시지를 출력한다.
O_APPEND : 파일의 맨 뒤에 내용을 추가한다.
O_TRUNC : 파일을 생성할 때 이미 있는 파일이고 쓰기 옵션으로 열었으면 내용을 모두 지우고 파일의 길이를 0으로 변경한다.
O_SYNC/O_DSYNC : 저장장치에 쓰기가 끝나야 쓰기 동작을 완료
위의 Flags는 OR bit operation "|" 를 사용하여 조합이 가능합니다.
// ex)
O_WRONLY | O_TRUNC // 파일을 쓰기 모드로 열고, 처음부터 쓰겠다 (내용이 있으면 삭제)
O_RDWR | O_APPEND // 파일을 읽기, 쓰기 모드로 열고 이어서 작성하겠다. (내용 삭제 x)
1-2 Close
$ man -s 2 close
fildes : file descriptor
return : if success, return 0
if error, return -1
close는 file descriptor를 파라미터로 받고 그에 해당하는 file을 닫습니다.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(void){
int fd;
mode_t mode;
mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
fd = open("hello.txt", O_CREAT | O_EXCL, mode);
if (fd == -1) {
perror("EXCL");
exit(1);
}
close(fd);
return 0;
}
위의 예시는 "hello.txt"라는 파일을 생성하는 예시입니다.
flag 값으로 O_CREAT | O_EXCL 을 주었기 때문에, 파일이 존재한다면 에러 메시지를 출력합니다.
위의 코드를 컴파일한 후 2회 연속으로 실행해보겠습니다.
첫번째 실행에서는 hello.txt라는 파일이 생성되었습니다.
두번째 실행에서는 이미 hello.txt라는 파일이 있기 때문에 O_CREAT | O_EXCL 옵션에 의해 에러메시지를 출력합니다.
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int openFile(void){
int fd = open("hello.txt", O_RDWR);
if (fd == -1){
perror("File Open");
exit(1);
}
return fd;
}
int main(void){
int fd = 0;
fd = openFile();
printf("fd = %d\n", fd);
close(fd);
close(0);
fd = openFile();
printf("fd = %d\n", fd);
close(fd);
return 0;
}
다음 예시는 file descriptor 값을 확인하는 예시입니다.
0, 1, 2번에는 default 값이 할당되어 있기 때문에 처음 print문에서는 그 다음 번호인 3을 출력합니다.
close(0)을 통해 default로 할당된 값을 삭제해주고 file descriptor를 확인하면 0이 출력됩니다.
다음 포스팅에는 Read/Write에 관하여 포스팅 하겠습니다.
'[컴퓨터공학] > [시스템 프로그래밍]' 카테고리의 다른 글
[시스템 프로그래밍] 파일 정보 검색(1) - inode 정보 검색 (2) | 2022.10.15 |
---|---|
[시스템 프로그래밍] Low-level File IO(3) - File access methods (0) | 2022.09.27 |
[시스템 프로그래밍] Low-level File IO(2) - Read, Write (0) | 2022.09.22 |