본문 바로가기

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

[시스템] 10. File Offset

1. File Offset

  • File Offset: Location in the file을 의미한다. read() 나 write() 콜이 다음에 어디에서 작업할지를 가리킨다.
  • 파일이 오픈될 경우 시작점을 가리킨다. (offset 0)

 

2. lseek(): File Offset 위치 변경

$\verb|off_t lseek(fd, pos, origin)|$

파일 offset 의 위치를 임의의 위치로 변경한다. 변경 모드는 아래 origin의 값에 따라 달라진다.

  • $\verb|SEEK_CUR|$: 현재 위치 + pos 로 이동
  • $\verb|SEEK_END|$: (파일의 끝+1) + pos 로 이동 (pos가 -1이면 파일의 마지막 위치)
  • $\verb|SEEK_SET|$: pos 로 이동

 

사용 예시

  • $\verb|lseek(fd, 0, SEEK_SET)|$: 파일의 start
  • $\verb|lseek(fd, 0, SEEK_END)|$: 파일의 end + 1
  • $\verb|lseek(fd, -1, SEEK_END)|$: 파일의 end
  • $\verb|lseek(fd, -10, SEEK_CUR)|$: 현재 파일 위치 - 10
  • $\verb|lseek(fd, 10000, SEEK_END)|$: 파일의 end + 10001 -> 10000바이트의 File hole 이 생성됨

offset이 파일의 end 위치를 지나서 가리킬 경우에는 read() 가 0을 리턴(EOF) 하고, File hole 이 생성된다.

 

3. pread, pwrite(): lseek 기능 포함

$\verb|ssize_t pread(fd, void *buf, size_t count, pos)|$
$\verb|ssize_t pwrite(fd, void *buf, size_t count, pos)|$

기존의 read(), write()에다가 pos 위치에서 시작하는 기능이 추가된 시스템 콜이다. 하지만 현재 offset은 무시하고 기능만 유사하게 작동하는 것이므로 실제 파일 offset이 pos 위치로 업데이트 되지는 않는다!

 

4. file descriptor의 공유

1. 부모 프로세스와 자식 프로세스가 같은 file discriptor를 공유할 수 있는데, 이 경우 파일 offset도 같이 공유가 된다. 따라서 파일을 읽을 때 파일 offset을 쓰고자 하는 위치로 변경한 뒤에 I/O 작업을 해줘야 한다.

2. 한번 파일을 open한 뒤에 fork() 하여 부모와 자식 프로세스가 사용한 후에 각각 close()를 해도 괜찮다. 그 이유는 부모와 자식 프로세스가 같은 파일 엔트리를 가리키는데, 여기에 Reference Count 정보가 2로 저장되어 있기 때문이다. close() 함수는 Reference Count를 1 감소시키는 역할을 하고, 0이 될때만 free 시켜준다.

 

fd = creat("file1.txt", S_IRUSR);

fork()

close(fd); // Ref = 2 -> close 두번 수행 후 free 시켜줌