본문 바로가기
전공/유닉스

2장. 파일 입출력 (2)

by 임 낭 만 2023. 10. 23.

lseek와 임의 접근

  • open된 file내의 특정 위치로 file pointer를 이동 시키는 system call
  • 사용법 :
#include <sys/types.h>
#include <unistd.h>

off_t lseek(int filedes, off_t offset, int whence);
//두번째, 세번째 인자 : 내가 원하는 위치 지정해 줌
//마지막 인자 : 기준점
  • 인수 사용법 :
    • filedes : open된 file의 file descriptor
    • whence : whence에서 offset 만큼 떨어진 위치로 이동
      • whence 위치는 아래 위치 중 선택:
        • SEEK_SET : file 시작 지점
        • SEEK_CUR : 현재 file 위치
        • SEEK_END : file의 끝 지점
    • offset : whence에서 offset 만큼 떨어진 위치로 이동; +/- 로 방향 설 정 가능;
    • return 값 : 이동된 위치 (시작점부터의 위치); 이동 실패 시 -1;
//맨 처음 상태 : data1 없음
int main(void) {
	int in[10] = { 1, 2, 3, 4, 5 }, fd, i, p, N, n;

	fd = open("data1", O_RDWR | O_CREAT, 0600);

	p = lseek(fd, 0, SEEK_SET);
	printf("%d\n", p);
	//0 출력
	p = lseek(fd, 0, SEEK_END);
	printf("%d\n", p);
	//0 출력
	p = lseek(fd, 0, SEEK_CUR);
	printf("%d\n", p);
	//0 출력

	for (i = 0; i < 5; i++) {
		write(fd, in + i, sizeof(int));
		p = lseek(fd, 0, SEEK_CUR);
		printf("%d\n", p);	//파일 포인터의 위치를 알아내는 명령
		//4, 8, 12, 16, 20 출력됨
		//write를 할 때마다 파일 포인터는 마지막으로 쓴 위치의 다음 위치 가리킴
	}
	p = lseek(fd, 0, SEEK_SET);
	printf("%d\n", p);
	//0 출력 (항상 파일의 첫 위치이므로)
	p = lseek(fd, 0, SEEK_END);
	printf("%d\n", p);
	//20 출력 (마지막으로 쓰인 것 다음 위치 가리킴)
    
	p = lseek(fd, -4, SEEK_END);	//앞 쪽으로
	read(fd, &N, sizeof(int));
	printf("%d ... %d", p, N);
	//16 5(마지막 숫자의 시작점으로 갔음) 출력
	p = lseek(fd, 0, SEEK_CUR);
	printf(" ... %d\n", p);
	//(16위치의 4바이트의 숫자를 읽었으므로) 20 출력

	p = lseek(fd, +4, SEEK_END);
	n = read(fd, &N, sizeof(int));
	printf("%d ... %d ... %d\n", p, N, n);
	//24 5 0 출력 (뒤 쪽에는 숫자가 없으므로 N 값이 변하지 않음)
	write(fd, in, sizeof(int));
	p = lseek(fd, 0, SEEK_CUR);
	printf("%d\n", p);
	//28 출력 (in의 첫 숫자가 쓰임)

	lseek(fd, 0, SEEK_SET);
	for (i = 0; i < 10; i++) {
		n = read(fd, &N, sizeof(int));
		printf("%d ... %d\n", N, n);
	}

	p = lseek(fd, -4, SEEK_SET);
	printf("%d\n", p);	//-1 출력
	p = lseek(fd, +4, SEEK_SET);
	printf("%d\n", p);	//4 출력

	return 0;
}

file의 제거

 

  • file을 삭제(?)하는 명령
  • 사용법 :
#include <unistd.h>
int unlink(const char *filename);

#include <stdio.h>
int remove(const char *filename)

//파일을 오픈하고 지우지 않으므로 filename을 적어야함
  • 주의 사항 :
    • include file이 다르다!
    • file descriptor가 아니라, file 이름을 쓴다!
    • 성공시 0; 실패 시 -1 return;
    • file이 open 되어 있는 상태면?
  • 차이점 : unlink는 file 만 삭제(?), remove는 file과 빈 directory도 삭제
int main(void) {
	int in[10] = { 1, 2, 3, 4, 5 }, fd, i, p, N, n;

	fd = open("data1", O_RDWR);
	unlink("data1");

	write(fd, in, 10 * sizeof(int));
	p = lseek(fd, 0, SEEK_SET);  //파일포인터가 파일의 마지막 부분에 있으므로 맨처음으로 옮김
	for (i = 0; i < 10; i++) {
		read(fd, &N, sizeof(int));
		printf("%d", N);
	}

	return 0;
}
//unlink 명령은 파일 이름만 삭제함
//따라서 파일을 오픈한 상태로 unlink를 해도 읽기 쓰기 가능
//단, 이 프로그램이 끝나면 파일 이름이 없으므로 다시 오픈 불가능

표준 입력, 표준 출력, 표준 오류

  • 표준 입력(키보드) : fd=0
  • 표준 출력(터미널 화면) : fd=1
  • 표준 오류(터미널 화면) : fd=2
int main(void) {
	char ch1[30], ch2[15] = "error message\n";
	int n;

	n = read(0, ch1, 30);	//표준 입력
	write(1, ch1, n);	//표준 출력 (읽은 n바이트만큼 출력해야 함)
	write(2, ch2, 15);	//표준 오류 출력

	return 0;
}

표준 입출력의 변경

  • redirection :
$ ./a.out < infile (infile이 file descriptor 0.)
$ ./a.out > outfile (outfile이 file descriptor 1.)
$ ./a.out < infile > outfile
  • pipe :
$ ./a.out1 | ./a.out2
(a.out1의 표준 출력이 a.out2의 표준 입력으로)

오류 메시지 출력

  • 예 :
    • perror("error … ");
      → error … : No such file or directory

'전공 > 유닉스' 카테고리의 다른 글

6장. 프로세스 생성과 실행  (1) 2023.11.01
5장. 프로세스 정보  (0) 2023.11.01
4장. 시스템 정보  (0) 2023.11.01
3장. 파일과 디렉토리  (1) 2023.11.01
2장. 파일 입출력 (1)  (1) 2023.10.05

댓글