3.4 lseek
파일 입출력 작업을 할 때 lseek 함수를 이용하여 원하는 위치로 이동할 수 있습니다. 현재 작업하고 있는 파일의 시작 위치에서 상대적 거리를 파일 offset이라 부르며 lseek 함수를 이용하면 파일의 시작 위치나 현재 위치, 파일의 끝에서 상대적 거리로 이동할 수 있습니다. 하지만 FIFO나 pipe처럼 특수한 파일은 lseek를 허용하지 않습니다.
#include <sys/types.h> #include <unistd.h> off_t lseek(int fd, off_t offset, int whence); 반환 값: 함수를 수행한 이후에 새로운 offset, 실패 시 -1 whence SEEK_SET: 파일의 시작 위치를 기준 SEEK_CUR: 파일의 현재 작업 위치를 기준 SEEK_END: 파일의 끝을 기준 |
다음은 lseek 함수의 리턴값을 확인하여 lseek 함수를 사용할 수 있는 파일인지 확인하는 코드입니다.
//ex_ enable_lseek.c #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> int main(int argc,char **argv) { int fd = 0; if(argc != 2) { fprintf(stderr,"usage: %s [filename]\n",argv[0]); return 1; } fd = open(argv[1],O_RDONLY); if(fd == -1) { perror("failed open dummy file."); return 1; } if(lseek(fd, 0, SEEK_CUR)==-1) { printf("can't lseek %s file. \n",argv[1]); } else { printf("can lseek %s file. \n",argv[1]); } close(fd); return 0; } |
이를 테스트 할 때는 root 계정으로 실행하세요.
$ ./ex_enable_lseek dummy
can lseek dummy file.
$ ./ex_enable_lseek /dev/tty0
can't lseek /dev/tty0 file.
lseek를 이용하여 파일의 끝보다 뒤로 이동한 후에 쓰기 작업을 하면 파일의 크기는 커지면서 빈 공간(hole)이 생깁니다. 내용을 확인하면 빈 공간(hole)은 '\0'로 보입니다.
다음은 새로운 파일을 생성한 후 lseek 함수 호출 후에 1바이트 더미 내용을 write하여 Hole을 만드는 예제 코드입니다.
// ex_hole.c #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> int main(int argc,char **argv) { int fd = 0; if(argc != 2) { fprintf(stderr,"usage: %s [filename]\n",argv[0]); return 1; } fd = open(argv[1],O_WRONLY|O_CREAT|O_TRUNC|O_EXCL,0644); if(fd == -1) { fprintf(stderr,"failed open %s\n",argv[1]); return 1; } if(lseek(fd, 20, SEEK_CUR)==-1) { printf("can't lseek %s file. \n",argv[1]); } else { char dummy='a'; write(fd,&dummy,1); } close(fd); return 0; } |
컴파일 한 후에 이를 실험하면 다음처럼 빈 공간이 있는 파일이 생긴 것을 확인할 수 있습니다. 참고로 od 명령은 파일의 내용을 8진수로 dump 하여 보여주며 -c 옵션을 사용하면 ASCII 코드를 확인할 수 있습니다. 자세한 사항은 man od로 확인하세요.
$ ./ex_hole dummy
$ ls -l dummy
-rw-r--r-- 1 ehpub 21 2015-02-14 11:11 dummy
$ od -c dummy
00000000 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
00000020 \0 \0 \0 \0 \a
00000025
앞으로 소스 코드를 표현할 때 공통적으로 사용하는 내용은 #include "eh.h"로 표시할게요. 그리고 새로운 헤더 파일을 포함할 필요가 있으면 무엇을 추가하였는지 알리기로 하겠습니다.
현재 eh.h 파일의 내용은 다음과 같습니다.
// eh.h #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <limits.h> #include <stdlib.h> |
'프로그래밍 기술 > 리눅스(Unix) 시스템 프로그래밍' 카테고리의 다른 글
stst 시스템 호출로 파일 종류 확인 (1) | 2016.10.31 |
---|---|
파일의 상태, fstat, lstat, stat 시스템 호출 (1) | 2016.10.31 |
[리눅스/유닉스 시스템 프로그래밍] fnctl, sync, fsync (0) | 2016.04.05 |
[리눅스/유닉스 시스템 프로그래밍] dup, dup2 (0) | 2016.04.05 |
[리눅스/유닉스 시스템 프로그래밍] 파일 테이블과 파일 디스크립터 테이블 (2) | 2016.04.05 |
[리눅스/유닉스 시스템 프로그래밍] read, write (0) | 2016.04.05 |
[리눅스/유닉스 시스템 프로그래밍] open, close (0) | 2016.04.05 |
[리눅스/유닉스] 파일 입출력 (0) | 2016.04.05 |
[리눅스/유닉스 시스템 프로그래밍] 파일 시스템 (0) | 2016.04.05 |
[리눅스/유닉스 시스템 프로그래밍] GCC 컴파일러 사용법 (0) | 2016.04.05 |