C,C++ & Linux

C/C++ lseek 함수 - 파일 커서(seek pointer) 조정

KyooDong 2020. 4. 22. 00:23
728x90

lseek 기능

함수의 seek pointer (커서) 를 조정하는 함수입니다.

조정된 seek pointer 는 파일의 read/write 시 사용됩니다.

특정 위치부터 읽거나 쓰고싶을때 유용합니다.

 

파일을 처음 열면 최초의 seek position 은 0입니다.

O_APPEND 플래그를 주어 열게되면 최초의 seek position 은 파일의 끝에 있습니다.

함수 원형

#include <unistd.h>
#include <sys/types.h>

off_t lseek(int fd, off_t offset, int whence);

매개변수

int fd

조정할 파일의 파일 디스크립터

 

off_t offset

기준점으로부터 이동할 거리(offset)

 

int whence

기준점

SEEK_SET(0) : 파일의 맨 앞

SEEK_CUR(1) : 현재 Seek 포인터

SEEK_END(2) : 파일의 맨 끝

반환값

성공 시 위치한 Seek pointer 위치, 에러 시 -1 리턴하고 errno 설정

예제

<ssu_test.txt>
Linux System Programming!
Unix System Programming!
Linux Mania
Unix Mania


<main.c>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int main() {
	char *fname = "ssu_test.txt";
	int fd;
	off_t fsize;

	if ((fd = open(fname, O_RDONLY)) < 0) {
		fprintf(stderr, "open error for %s\n", fname);
		exit(1);
	}

	// SEEK_END(파일의 끝) 의 seek position 은 파일 size 와 같다.
	if ((fsize = lseek(fd, 0, SEEK_END)) < 0) {
		fprintf(stderr, "lseek error\n");
		exit(1);
	}

	printf("The size of <%s> is %ld bytes.\n", fname, fsize);
	exit(0);
}

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

// 유저 읽기, 쓰기  그룹 읽기,  기타 사용자 읽기 권한
#define CREAT_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

char buf1[] = "1234567890";
char buf2[] = "ABCDEFGHIJ";

int main() {
	char *fname = "ssu_hole.txt";
	int fd;

	// hole 파일 생성
	if ((fd = creat(fname, CREAT_MODE)) < 0) {
		fprintf(stderr, "creat error for %s\n", fname);
		exit(1);
	}

	// 1234567890 (10개) 를 넘어서 NULL 문자 + 그 다음 주소까지 저장( mac os 에서는 buf2[0]임)
	if (write(fd, buf1, 12) != 12) {
		fprintf(stderr, "buf1 write error\n");
		exit(1);
	}

	// 15000바이트만큼 이동
    // 현재 파일보다 큰 seek position 으로 lseek 하면 널문자('\0')로 빈 공간을 채우며
    // 이를 hole 이라고 부름
	if (lseek(fd, 15000, SEEK_SET) < 0) {
		fprintf(stderr, "lseek error\n");
		exit(1);
	}

	// 15000바이트 떨어진 곳에 ABCDEFGHIJ\0\0 쓰기
	if (write(fd, buf2, 12) != 12) {
		fprintf(stderr, "buf2 write error\n");
		exit(1);
	}
	exit(0);
}

hexdump 는 파일을 16진수로 열어주는 함수입니다. -C 옵션을 붙여주면 오른쪽에 Ascii 로도 보여줍니다.

Mac os 기준으로 첫째 줄에 A가 찍혀있는걸 볼 수 있습니다.

buf1, buf2 가 실제 메모리 상에서 연속하여 할당됐기 때문입니다.

리눅스에서는 해당 현상이 발생하지 않으니 확인해보시면 좋을것같습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

리눅스시스템프로그래밍 저자 : 홍지만
https://book.naver.com/bookdb/book_detail.nhn?bid=14623672

책에 기술된 예제 프로그램입니다. 책 내부에는 훨씬 더 많은 자료가 있습니다. (개인적으로 좋았습니다.)