본문 바로가기

학부 수업 정리/시스템프로그래밍 (21-2)

[시스템] 9. File I/O 기초

1. 파일 시스템 용어

  • File Table: 오픈된 파일들을 저장하고 있는 리스트
  • File desciptors (fds): 파일의 인덱싱 방식 (int type, start at 0) 
  • File offset (position): 파일 내 포인터
  • 포함해야할 헤더파일: $\verb|<unistd.h>, <fcntl.h>, <sys/stat.h>|$

 

2. open(), creat(): Opening Files

$\verb|int open(*name, flags)|$
$\verb|int open(*name, O_CREAT, mode)|$

성공적으로 파일이 open 되면 fd에 파일이 Mapping 된다.

  • flags: 반드시 $\verb|O_RDONLY, O_WRONLY, O_RDWR|$ 중 하나는 꼭 써야 한다. 그 외에는 비트 연산자로  $\verb|O_CREAT, O_TRUNC|$ (생성, 기본 파일 삭제 후 덮어쓰기) 와 같은 플래그들을 사용할 수 있다.
  • mode: $\verb|O_CREAT|$ 를 사용할 경우 추가해야 한다. 아래와 같이 권한 설정이 가능하다.

 

$\verb|int creat(*name, mode)|$

$\verb|int open(*name, O_WRONLY O_CREAT O_TRUNC, mode)|$ 와 동일하다. (비트 연산자로 flag 구분해야 됨)

 

3. read(): Reading Files

$\verb|ssize_t read(int fd, void *buf, size_t len)|$
  • fd로부터 파일을 읽어서 buf에 저장한다. len에는 버퍼의 크기를 넣어줘야 한다.
  • 성공할 경우 buf 에 저장된 정보의 바이트 수를 리턴한다. (최대 len)
  • EOF (End-of-file) 에 다다랐을 경우, 0을 리턴한다.
  • 오류가 있으면 -1을 리턴한다. 읽기 작업 중 시그널로부터 방해받은 경우에는 errno 에 $\verb|EINTR|$ 값이 저장된다.
ssize_t ret;
while (len != 0 && (ret = read (fd, buf, len)) != 0) {
  if (ret == -1) {
    if (errno == EINTR)
      continue;
      perror ("read");
      break;
    }
    
  // 버퍼 포인터 갱신
  len -= ret;
  buf += ret;
}

 

4. write(): Writing Files

$\verb|ssize_t write(int fd, void *buf, size_t count)|$
  • buf의 내용을 count 만큼 fd가 가리키는 파일에 저장한다.
  • 성공할 경우, write 된 정보의 바이트 수를 리턴하고, 실패할 경우 -1을 리턴한다.

 

Write 하라고 해서 disk 에 내용이 써졌다고 보장하진 못한다. 페이지 캐시에 저장해놓고 추후에 작성하기 때문이다... - 자세한 것은 운영체제 시간에 배움! -> $\verb|int fsync(fd)|$ 을 사용하면 현재 페이지 캐시에 있는 정보들을 디스크에 쓰는 작업을 수행한다. (성능 패널티가 존재함)

if (write(fd, str, len) < 0) {
  perror("write");
  close(fd);
}

 

5. close(): Closing Files

int close(int fd)

file descriptor 를 파일로부터 unmap 한다. 성공 시 0을 리턴하고, 에러 시 -1을 리턴한다.