[Linux/Unix] 저수준 파일 입출력

2023. 4. 8. 17:13CS/운영체제(OS)

저수준 파일 입출력
: 유닉스 커널의 시스템 호출을 사용하여 파일 입출력을 수행
  장점) 시스템 호출을 이용하므로 파일에 좀 더 빠르게 접근 가능
          바이트 단위로 파일의 내용을 다루므로, 일반 파일뿐만 아니라 특수 파일도 읽고 쓸 수 있다
  단점) 바이트 단위로만 입출력을 수행하므로, 이를 이용해서 응용 프로그램을 작성하려면 바이트를
          적당한 형태의 데이터로 변환하는 함수 등 여러 가지 추가적인 기능을 구현해야 한다

 


[파일 기술자]

: 현재 열려 있는 파일을 구분할 목적으로 유닉스가 붙여놓은 번호

   저수준 파일 입출력에서 열린 파일을 참조하는 데 사용하는 지시자 역할

   정수값, open 함수를 사용해 파일을 열었을 때 부여된다

 

0 : 표준 입력 (보통 키보드)

1 : 표준 출력 (보통 모니터 화면)

2 : 표준 오류 출력 (보통 모니터 화면)

 

프로세스는 동작하면서 필요에 따라 파일을 열고 닫는다. 한 프로세스가 동시에 열 수 있는 파일의 개수에는 제한이 있다. 이 개수를 변경하려면 유닉스 커널의 설정을 바꾼 후 재부팅해야 한다. 프로세스가 파일을 열 때 파일 기술자는 0번부터 시작해 가장 작은 번호가 자동으로 할당된다. 프로세스가 처음 동작할 때 세 파일 기술자(0, 1, 2)는 기본적으로 할당된다. 따라서 프로세스가 파일을 처음 열면 3번 파일 기술자가 할당된다. 물론 0번이나 1번, 2번 파일 기술자를 닫아놓았을 경우에는 이들 번호도 할당될 수 있다. 

 

 


 

[파일 생성과 열고 닫기]

파일을 읽고 쓰려면 먼저 파일을 열어야 한다. 파일을 연다는 것은 파일의 내용을 읽거나, 파일에 내용을 쓸 수 있는 상태로 변경하는 일을 의미한다. 파일에 대한 작업을 완료하면 파일을 닫아야 한다. 그래야 파일의 내용을 하드 디스크에 온전히 기록하고 파일이 사용한 버퍼 등을 반납할 수 있다.

 

[파일 열기 : open(2)]

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *path, int oflag [, mode_t mode]);

path : 열려는 파일이 있는 경로

oflag : 파일 상태 플래그

mode : 접근 권한

 

파일을 여는 데는 open 함수를 사용한다. open 함수는 path에 지정한 파일을 oflag에 지정한 상태 플래그의 값에 따라 열고 파일 기술자를 반환한다.

 

파일의 상태를 조정하는 oflag 값은 <sys/fcntl.h> (/usr/include/sys/fcntl.h) 파일에 #define O_RDWR 2와 같이 정의되어 있다. oflag의 주요 플래그는 다음과 같다.

 

주요 oflag

종류 기능
O_RONLY 파일을 읽기 전용으로 연다
O_WRONLY 파일을 쓰기 전용으로 연다
O_RDWR 파일을 읽기/쓰기 전용으로 연다
O_CREAT 파일이 없으면 생성한다. 파일을 생성할 권한은 당연히 있어야 한다. 파일이 이미 있다면 아무 의미 없는 옵션이다.
O_EXCL O_CREAT 옵션과 함께 사용할 경우 기존에 없는 파일이면 파일을 생성하지만, 이미 있으면 파일을 생성하지 않고 오류를 출력한다.
O_APPEND 이 옵션을 지정하면 파일의 맨 끝에 내용을 추가한다.
O_TRUNC 파일을 생성할 때 이미 있는 파일이고, 쓰기 옵션으로 열었으면 내용을 모두 지우고 파일의 길이를 0으로 변경한다.
O_NONBLOCK/O_NDELAY 비블로킹(non-blocking) 입출력 옵션으로 파일을 읽거나 쓰고 난 후의 동작에 영향을 준다. 디스크의 파일 입출력보다는 FIFO 같은 특수 파일의 입출력에 의미가 있다. 디스크인 경우 읽거나 쓸 데이터가 없으면 -1을 리턴한다.
O_SYNC/O_DSYNC 파일에 쓰기 동작을 할 때 보통 버퍼에만 쓰고 나중에 디스크와 같은 저장 장치로 옮겨 쓰는데, 이 옵션이 설정되어 있으면 저장 장치에 쓰기를 마쳐야 쓰기 동작을 완료한다. O_SYNC 플래그는 파일의 수정 시각 속성도 수정할 때까지 기다린다. 이 옵션을 설정하면 프로그램의 실행 속도는 느려질 수 있지만 디스크에 확실하게 저장됨을 보장한다.

 

플래그를 OR(|) 연산자로 연결해 지정할 수 있다. 예를 들어, 다음과 같이 파일의 용도에 따라 플래그를 지정하면 된다.

 

쓰기 전용으로 열 때, 이미 파일이 있는 경우 O_WRONLY | O_TRUNC
쓰기 전용으로 열 때, 파일이 없는 경우 O_WRONLY | O_CREAT | O_TRUNC
읽기/쓰기/추가용으로 열 때 O_RDWR | O_APPEND

 

mode는 파일의 접근 권한을 설정하는 것으로, O_CREAT 플래그를 지정해 파일을 생성할 때만 사용한다. mode는 일반적으로 파일 권한을 설정하듯이 0644와 같이 지정할 수도 있지만, <sys/stat.h> 파일에 정의된 플래그를 사용할 수도 있다.

 

설정 가능한 mode 종류

플래그 모드 설명
S_IRWXU 0700 소유자 읽기/쓰기/실행 권한
쓰기귀찬티비    
     
     
     
     
     
     
     
     
     
     

 

open 함수는 파일 열기에 성공하면 파일 기술자를 리턴한다. 파일 열기에 실패하면 -1을 리턴하고, 외부 변수 errno에 실패한 이유를 설명하는 오류 코드를 저장한다. 코드를 perror 함수로 출력하면 해당 메시지를 확인할 수 있다.

 


 

[파일 생성 : creat(2)]

#include <sys/stat.h>
#include <fcntl.h>

int creat(const char *path, mode_t mode)l

인자설명

path : 파일을 생성할 경로

mode : 접근 권한

 

파일을 생성하는 전용 함수로 creat가 있는데, open 함수에 파일 생성 기능이 없었던 구버전 유닉스에서 사용하던 것이다. creat 함수는 open 함수와 달리 옵션을 지정하는 부분이 없다.

 

아래에서 creat 함수와 open 함수는 같은 의미다.

 

creat(path, mode);

open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);

 

creat 함수로 파일을 생성하면 파일 기술자가 리턴되므로, 별도로 open 함수를 호출해 파일을 열 필요가 없다.