1 / 52

파일 입출력

2. 파일 입출력. 학습 목표. 유닉스에서 파일 입출력의 특징을 이해한다 . 저수준 파일 입출력 함수를 사용할 수 있다 . 고수준 파일 입출력 함수를 사용할 수 있다 . 임시 파일을 생성해 파일 입출력을 할 수 있다. 저수준 파일입출력 & 고수준 파일입출력 비교 저수준 파일입출력 프로그래밍 고수준 파일입출력 프로그래밍 저수준 및 고수준 파일입출력 인터페이스 변환 임시 파일 생성. 목 차. 파일 (File) 논리적 : 관련있는 데이터의 집합 ( 모음 )

mikko
Download Presentation

파일 입출력

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 2 파일 입출력

  2. 학습 목표 • 유닉스에서 파일 입출력의 특징을 이해한다. • 저수준 파일 입출력 함수를 사용할 수 있다. • 고수준 파일 입출력 함수를 사용할 수 있다. • 임시 파일을 생성해 파일 입출력을 할 수 있다.

  3. 저수준 파일입출력 & 고수준 파일입출력 비교 저수준 파일입출력 프로그래밍 고수준 파일입출력 프로그래밍 저수준 및 고수준 파일입출력 인터페이스 변환 임시 파일 생성 목 차

  4. 파일(File) 논리적 : 관련있는 데이터의 집합(모음) => 응용프로그램에서의 기본적인 입출력 객체 물리적: 하드디스크와 같은 저장장치에 데이터를 저장하는 단위 특수 파일 데이터 저장 목적이 아닌 특정 객체의 인터페이스 목적으로 생성된 파일 예: 장치 파일(Device File) => 입출력 장치의 인터페이스를 목적으로 추상화된 파일 파일 입출력 파일에 데이터를 쓰거나 읽는 동작 응용 프로그램은 C 표준 입출력 라이브러리나 OS가 제공하는 입출력 시스템호출을 이용하여 파일 입출력을 수행할 수 있다 고수준(High-level) 파일입출력 인터페이스 : C 표준 입출력 라이브러리 함수 저수준(Low-level) 파일입출력 인터페이스 : OS 입출력 시스템호출 함수 파일 및 파일 입출력

  5. 저수준 및 고수준 파일입출력 비교

  6. 파일 기술자 (File Descriptor) 현재 열려있는 파일을 구분하는 정수값 저수준 파일 입출력에서 열린 파일을 참조하는데 사용 0번 : 표준 입력, 1번 : 표준 출력, 2번 : 표준 오류 저수준 파일입출력 : 파일 기술자 • 파일 기술자 테이블(File Descriptor Table)의 인덱스 • 프로세스별로 하나의 파일 기술자 테이블을 가짐 • 프로세스 생성 시에 기본적으로 표준입력, 표준출력, 표준오류 파일은 미리 생성(열림)

  7. 파일 열기: open(2) path에 지정한 파일을 oflag에 지정한 플래그 값에 따라 열고 파일기술자를 반환 oflag 값 : 저수준 파일입출력 : 파일 생성과 열고 닫기 (1) #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *path, intoflag [, mode_t mode]);

  8. 파일 열기: open(2) mode : 파일 접근권한 지정, 0644같이 숫자나 플래그 값으로 지정 가능 저수준 파일입출력 : 파일 생성과 열고 닫기 (2) mode=S_IRUSR | S_IWUSR;

  9. 파일 생성 : creat(2) 파일 생성 함수, open 함수에 파일 생성 기능이 없던 구버전 유닉스에서 사용 open 함수와 달리 옵션을 지정하는 부분이 없다. creat 함수로 파일을 생성하면 파일 기술자를 반환하므로 별도로 open할 필요 없음 파일 닫기: close(2) 프로세스에서 열 수 있는 파일 개수가 제한되어 있으므로 파일의 사용이 끝나면 닫아야 한다. 저수준 파일입출력 : 파일 생성과 열고 닫기 (3) #include <sys/stat.h> #include <fcntl.h> intcreat(const char *path, mode_t mode); #include <unistd.h> int close(intfildes);

  10. [예제 2-1] 새 파일 열고 닫기 ex2_1.c 01 #include <sys/types.h> 02 #include <sys/stat.h> 03 #include <fcntl.h> 04 #include <unistd.h> 05 #include <stdlib.h> 06 #include <stdio.h> 07 08 int main(void) { 09 intfd; 10 mode_t mode; 11 12 mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 13 14 fd = open("unix.txt", O_CREAT, mode); 15 if (fd == -1) { 16 perror("Creat"); 17 exit(1); 18 } 19 close(fd); 20 21 return 0; 22 } # ls unix.txt unix.txt: 해당 파일이나 디렉토리가 없음਺ # gcc -o ex2_1.out ex2_1.c # ex2_1.out# ls -l unix.txt -rw-r--r-- 1 root other 0 1월 6일 13:10 unix.txt 접근권한:644

  11. [예제 2-2] O_EXCL 플래그 사용하기 ex2_2.c 01 #include <sys/types.h> 02 #include <sys/stat.h> 03 #include <fcntl.h> 04 #include <unistd.h> 05 #include <stdlib.h> 06 #include <stdio.h> 07 08 int main(void) { 09 intfd; 10 11 fd = open("unix.txt", O_CREAT | O_EXCL, 0644); 12 if (fd == -1) { 13 perror("Excl"); 14 exit(1); 15 } 16 close(fd); 17 18 return 0; 19 } # ls unix.txt unix.txt # ex2_2.out Excl: File exists # rm unix.txt # ex2_2.out # ls unix.txt unix.txt

  12. [예제 2-3] 파일 기술자 할당 ex2_3.c 01 #include <sys/types.h> 02 #include <sys/stat.h> 03 #include <fcntl.h> 04 #include <unistd.h> 05 #include <stdlib.h> 06 #include <stdio.h> 07 08 int main(void) { 09 intfd; 10 11 close(0); 12 13 fd = open("unix.txt", O_RDWR); 14 if (fd == -1) { 15 perror("Excl"); 16 exit(1); 17 } 18 19 printf("unix.txt : fd = %d\n", fd); 20 close(fd); 21 22 return 0; 23 } 표준입력(fd=0)를닫음 # ex2_3.out unix.txt : fd = 0 11행에서 0번을 닫았으므로 새로 생성한 파일은 가장 작은 번호인 0번이 할당된다.

  13. 파일 읽기 : read(2) 파일에서 nbytes로 지정한 크기만큼 바이트를 읽어서 buf에 저장 실제로 읽어온 바이트 개수를 반환 반환값이 0이면 파일의 끝에 도달했음을 의미 파일의 종류에 상관없이 무조건 바이트 단위로 읽어온다. 파일 쓰기 : write(2) buf가 가리키는 메모리에서 nbytes로 지정한 크기만큼 파일에 기록 실제로 쓰기를 수행한 바이트 수를 반환 저수준 파일입출력 : 파일 읽기와 쓰기 #include <unistd.h> ssize_t read(intfildes, void *buf, size_tnbytes); #include <unistd.h> ssize_t write(intfildes, const void *buf, size_tnbytes);

  14. [예제 2-4] 파일 읽기 ex2_4.c 01 #include <fcntl.h> 02 #include <unistd.h> 03 #include <stdlib.h> 04 #include <stdio.h> 05 06 int main(void) { 07 intrfd, wfd, n; 08 char buf[10]; 09 10 rfd = open("unix.txt", O_RDONLY); 11 if(rfd == -1) { 12 perror("Open unix.txt"); 13 exit(1); 14 } 15 16 wfd = open("unix.bak", O_CREAT | O_WRONLY | O_TRUNC, 0644); 17 if (wfd == -1) { 18 perror("Open unix.bak"); 19 exit(1); 20 } 21 파일기술자 2개 선언

  15. [예제 2-4] 파일 읽기 22 while ((n = read(rfd, buf, 6)) > 0) 23 if (write(wfd, buf, n) != n) perror("Write"); 24 25 if (n == -1) perror("Read"); 26 27 close(rfd); 28 close(wfd); 29 30 return 0; 31 } 6바이트씩 읽어온다 # ls unix.bak unix.bak: 해당 파일이나 디렉토리가 없음 # ex2_5.out # cat unix.bak Unix System Programming

  16. 파일 오프셋 위치 지정 : lseek(2) offset으로 지정한 크기만큼 오프셋을 이동시킨다. offset의 값은 whence값을 기준으로 해석한다. 파일 오프셋의 현재 위치를 알려면? 저수준 파일입출력 : 파일 오프셋 지정 #include <sys/types.h> #include <unistd.h> off_tlseek(intfildes, off_t offset, int whence); 파일의 시작에서 5번째 위치로 이동 lseek(fd, 5, SEEK_SET); lseek(fd, 0, SEEK_END); 파일의 끝에서 0번째, 즉 끝으로 이동 cur_offset = lseek(fd, 0, SEEK_CUR);

  17. [예제 2-6] 파일 오프셋 사용하기 ex2_6.c • ... • 07 int main(void) { • 08 intfd, n; • 09 off_t start, cur; • 10 char buf[256]; • 11 • 12 fd = open("unix.txt", O_RDONLY); • 13 if (fd == -1) { • 14 perror("Open unix.txt"); • 15 exit(1); • 16 } • 17 • 18 start = lseek(fd, 0, SEEK_CUR); • 19 n = read(fd, buf, 255); • 20 buf[n] = '\0'; • 21 printf("Offset start=%d, Read Str=%s, n=%d\n", (int)start, buf, n); • cur = lseek(fd, 0, SEEK_CUR); • 23 printf("Offset cur=%d\n", (int)cur); • 24

  18. [예제 2-6] 파일 오프셋 사용하기 25 start = lseek(fd, 5, SEEK_SET); 26 n = read(fd, buf, 255); 27 buf[n] = '\0'; 28 printf("Offset start=", Read Str=%s", (int)start, buf); 29 30 close(fd); 31 32 return 0; 33 } # ex2_6.out Offset start=0, Read Str=Unix System Programming, n=24 Offset cur=24 Offset start=5, Read Str=System Programming

  19. 파일 기술자 복사 : dup(2) 기존 파일 기술자를 인자로 받아 새로운 파일 기술자를 반환 새로운 파일 기술자는 현재 할당할 수 있는 파일 기술자 중 가장 작은 값으로 자동 할당 파일 기술자 복사 : dup2(3) 새로운 파일 기술자를 지정할 수 있다. 저수준 파일입출력 : 파일 기술자 복사 #include <unistd.h> int dup(intfildes); #include <unistd.h> int dup2(intfildes, int fildes2);

  20. [예제 2-7] 파일 기술자 복사하기 ex2_7.c 01 #include <fcntl.h> 02 #include <unistd.h> 03 #include <stdlib.h> 04 #include <stdio.h> 05 06 int main(void) { 07 intfd, fd1; 08 09 fd = open("tmp.aaa", O_CREAT | O_WRONLY | O_TRUNC, 0644); 10 if (fd == -1) { 11 perror("Create tmp.aaa"); 12 exit(1); 13 } 14 15 close(1); 16 17 fd1 = dup(fd); 18 19 printf("DUP FD=%d\n", fd1); 20 printf("Standard Output Redirection\n"); 21 close(fd); 22 23 return 0; 24 } 표준출력(1)을 닫았다 fd를 복사하면 가장 작은 값인 1로 복사 표준출력을 출력한 내용이 파일로 저장 # ex2_7.out # cat tmp.aaa DUP FD=1 Standard Output Redirection

  21. [예제 2-8] dup2 함수 사용하기 ex2_8.c 01 #include <fcntl.h> 02 #include <unistd.h> 03 #include <stdlib.h> 04 #include <stdio.h> 05 06 int main(void) { 07 intfd; 08 09 fd = open("tmp.bbb", O_CREAT | O_WRONLY | O_TRUNC, 0644); 10 if (fd == -1) { 11 perror("Create tmp.bbb"); 12 exit(1); 13 } 14 15 dup2(fd, 1); 16 17 printf("DUP2 : Standard Output Redirection\n"); 18 close(fd); 19 20 return 0; 21 } 표준출력(1)로 지정하여 복사 표준출력을 출력한 내용이 파일로 저장된다. # ex2_8.out # cat tmp.bbb DUP2 : Standard Output Redirection

  22. 파일 기술자 제어 : fcntl(2) 파일 기술자가 가리키는 파일에 “cmd"로 지정한 명령을 수행 “cmd"의 종류에 따라 인자(arg)를 지정할 수 있음 자주 사용하는 fcntl 명령 저수준 파일입출력 : 파일 기술자 제어 #include <sys/types.h> #include <unistd.h> #include <fcntl.h> intfcntl(intfildes, intcmd, /* arg */ ...);

  23. [예제 2-9] fcntl 함수로 파일 기술자 제어하기 ex2_9.c 07 int main(void) { 08 intfd, flags; 09 10 fd = open("unix.txt", O_RDWR); 11 if (fd == -1) { 12 perror("open"); 13 exit(1); 14 } 15 16 if ((flags = fcntl(fd, F_GETFL)) == -1) { 17 perror("fcntl"); 18 exit(1); 19 } 20 21 flags |= O_APPEND; 22 23 if (fcntl(fd, F_SETFL, flags) == -1) { 24 perror("fcntl"); 25 exit(1); 26 } 27 28 if (write(fd, "Hanbit Media", 12) != 12) perror("write"); 29 close(fd); 30 31 return 0; 32 } 파일을 추가 모드로 수정 # cat unix.txt Unix System Programming # ex2_9.out # cat unix.txt Unix System Programming Hanbit Media 파일에 내용 추가

  24. unlink(2) path에 지정한 파일의 inode에서 링크 수를 감소시킨다. 링크 수가 0이 되면 path에 지정한 파일이 삭제된다. 파일 뿐만 아니라 디렉토리(빈 디렉토리 아니어도 됨)도 삭제된다. remove(3) path에 지정한 파일이나 디렉토리를 삭제한다. 디렉토리인 경우 빈 디렉토리만 삭제한다. 저수준 파일입출력 : 파일 삭제 #include <unistd.h> int unlink(const char *path); #include <stdio.h> int remove(const char *path);

  25. [예제 2-10] unlink 함수로 파일 삭제하기 ex2_10.c 01 #include <unistd.h> 02 #include <stdlib.h> 03 #include <stdio.h> 04 05 int main(void) { 06 intcnt; 07 08 cnt = unlink("tmp.aaa"); 09 if (cnt == -1) { 10 perror("Unlink tmp.aaa"); 11 exit(1); 12 } 13 14 printf("Unlink tmp.aaa success!!!\n"); 15 16 return 0; 17 } tmp.aaa 파일 삭제 # ls -l tmp* -rw-r--r-- 1 root other 37 1월 6일 17:50 tmp.aaa -rw-r--r-- 1 root other 35 1월 6일 18:06 tmp.bbb # ex2_10.out Unlink tmp.aaa success!!! # ls -l tmp* -rw-r--r-- 1 root other 35 1월 6일 18:06 tmp.bbb

  26. fsync (3) 메모리에 위치하고 있는 파일 내용을 디스크로 보내 메모리와 디스크 내용을 동기화 디스크 입출력 속도를 향상시키기 위해 메모리에 디스크 캐시를 유지하며, 디스크 캐시의 내용과 디스크의 파일 내용을 동기화시킴 저수준 파일입출력 : 파일과 디스크 동기화 #include <unistd.h> intfsync(intfildes);

  27. 고수준 파일 입출력 : C 언어 표준 입출력 라이브러리 파일 포인터 고수준 파일 입출력에서 열린 파일을 가리키는 포인터 자료형으로 FILE * 형을 사용 -> 구조체에 대한 포인터 고수준 파일입출력 : 파일 포인터(File Pointer)

  28. 파일 열기: fopen(3) filename으로 지정한 파일을 mode로 지정한 모드에 따라 열고 파일 포인터를 반환 mode 값 고수준 파일입출력 : 파일 열기와 닫기 (1) #include <stdio.h> FILE *fopen(const char *filename, const char *mode); FILE *fp; fp = fopen("unix.txt", "r");

  29. 파일 닫기: fclose(3) fopen으로 오픈한 파일을 닫는다. 고수준 파일입출력 : 파일 열기와 닫기 (2) #include <stdio.h> intfclose(FILE *stream); : FILE *fp; fp = fopen("unix.txt", "r"); : fclose(fp); :

  30. 문자 기반 입력함수: fgetc(3), getc(3), getchar(3), getw(3) fgetc : 문자 한 개를 unsigned char 형태로 읽어온다. getc, getchar : 매크로 getw : 워드 단위로 읽어온다. 문자 기반 출력함수: fputc(3), putc(3), putchar(3), putw(3) 고수준 파일입출력 : 문자 기반 입출력 함수 #include <stdio.h> intfgetc(FILE *stream); intgetc(FILE *stream); intgetchar(void); intgetw(FILE *stream); #define getchar( ) fgetc(stdin) #include <stdio.h> intfputc(int c, *stream); intputc(int c, *stream); intputchar(int c); intputw(int w, FILE *stream); #define putchar(c) fputc(c, stdin)

  31. [예제 2-11] 문자 기반 입출력 함수 사용하기 ex2_11.c 01 #include <stdlib.h> 02 #include <stdio.h> 03 04 int main(void) { 05 FILE *rfp, *wfp; 06 int c; 07 08 if ((rfp = fopen("unix.txt", "r")) == NULL) { 09 perror("fopen: unix.txt"); 10 exit(1); 11 } 12 13 if ((wfp = fopen("unix.out", "w")) == NULL) { 14 perror("fopen: unix.out"); 15 exit(1); 16 } 17 18 while ((c = fgetc(rfp)) != EOF) { 19 fputc(c, wfp); 20 } 21 22 fclose(rfp); 23 fclose(wfp); 24 25 return 0; 26 } EOF를 만날 때까지 한 문자씩 읽어서 파일로 출력 # cat unix.txt Unix System Programming # ex2_11.out # cat unix.out Unix System Programming

  32. 문자열 기반 입력 함수: gets(3), fgets(3) gets : 표준 입력에서 문자열을 읽어들인다. fgets : 파일(stream)에서 n보다 하나 적게 문자열을 읽어 s에 저장 문자열 기반 출력 함수: puts(3), fputs(3) 고수준 파일입출력 : 문자열 기반 입출력 #include <stdio.h> char *gets(char *s); char *fgets(char *s, int n, FILE *stream); #include <stdio.h> char *puts(const char *s); char *fputs(const char *s, FILE *stream);

  33. [예제 2-12] 문자열 기반 입출력 함수 사용하기 ex2_12.c 01 #include <stdlib.h> 02 #include <stdio.h> 03 04 int main(void) { 05 FILE *rfp, *wfp; 06 char buf[BUFSIZ]; 07 08 if ((rfp = fopen("unix.txt", "r")) == NULL) { 09 perror("fopen: unix.txt"); 10 exit(1); 11 } 12 13 if ((wfp = fopen("unix.out", "a")) == NULL) { 14 perror("fopen: unix.out"); 15 exit(1); 16 } 17 18 while (fgets(buf, BUFSIZ, rfp) != NULL) { 19 fputs(buf, wfp); 20 } 21 22 fclose(rfp); 23 fclose(wfp); 24 25 return 0; 26 } 한 행씩 buf로 읽어서 파일로 출력 # ex2_12.out # cat unix.out Unix System Programming Unix System Programming

  34. 버퍼 기반 입력함수: fread(3) 항목의 크기가 size인 데이터를 nitems에 지정한 개수만큼 읽어 ptr에 저장 성공하면 읽어온 항목 수를 반환 읽을 항목이 없으면 0을 반환 버퍼 기반 출력함수: fwrite(3) 항목의 크기가 size인 데이터를 nitems에서 지정한 개수만큼 ptr에서 읽어서 stream으로 지정한 파일에 출력 성공하면 출력한 항목의 수를 반환 오류가 발생하면 EOF(-1)를 반환 고수준 파일입출력 : 버퍼 기반 입출력 #include <stdio.h> size_tfread(void *ptr, size_t size, size_tnitems, FILE *stream); #include <stdio.h> size_tfwrite(const void *ptr, size_t size, size_tnitems, FILE *stream);

  35. [예제 2-13] fread 함수로 파일 읽기 ex2_13.c 01 #include <stdlib.h> 02 #include <stdio.h> 03 04 int main(void) { 05 FILE *rfp; 06 char buf[BUFSIZ]; 07 int n; 08 09 if ((rfp = fopen("unix.txt", "r")) == NULL) { 10 perror("fopen: unix.txt"); 11 exit(1); 12 } 13 14 while ((n=fread(buf, sizeof(char)*2, 3, rfp)) > 0) { 15 buf[6] = '\0'; 16 printf("n=%d, buf=%s\n", n, buf); 17 } 18 19 fclose(rfp); 20 21 return 0; 22 } # ex2_13.out n=3, buf=Unix S n=3, buf=ystem n=3, buf=Progra n=3, buf=mming

  36. [예제 2-14] fwrite 함수로 파일 출력하기 ex2_14.c 01 #include <stdlib.h> 02 #include <stdio.h> 03 04 int main(void) { 05 FILE *rfp, *wfp; 06 char buf[BUFSIZ]; 07 int n; 08 09 if ((rfp = fopen("unix.txt", "r")) == NULL) { 10 perror("fopen: unix.txt"); 11 exit(1); 12 } 13 14 if ((wfp = fopen("unix.out", "a")) == NULL) { 15 perror("fopen: unix.out"); 16 exit(1); 17 } 18 19 while ((n = fread(buf, sizeof(char)*2, 3, rfp)) > 0) { 20 fwrite(buf, sizeof(char)*2, n, wfp); 21 } 22 23 fclose(rfp); 24 fclose(wfp); 25 26 return 0; 27 } 항목크기가 char크기의 2배, 이것을 3개, 즉 2*3=6바이트씩 읽어서 출력 # ex2_14.out # cat unix.out Unix System Programming Unix System Programming Unix System Programming

  37. 형식 기반 입력 함수: scanf(3), fscanf(3) fscanf도 scanf가 사용하는 형식 지정 방법을 그대로 사용한다. 성공하면 읽어온 항목의 개수를 반환 형식 기반 출력 함수: printf(3), fprintf(3) fprintf는 지정한 파일로 형식 지정 방법을 사용하여 출력한다. 고수준 파일입출력 : 형식 기반 입출력 #include <stdio.h> intscanf(const char *restrict format, ...); intfscanf(FILE *restrict stream, const char *restrict format, ..); #include <stdio.h> intprintf(const char *restrict format, /* args */ ...); intfprintf(FILE *restrict stream, const char *restrict format, /*args */ ..)/

  38. [예제 2-15] fscanf 함수 사용하기 ex2_15.c • 01 #include <stdlib.h> • 02 #include <stdio.h> • 03 • 04 int main(void) { • 05 FILE *rfp; • 06 int id, s1, s2, s3, s4, n; • 07 • 08 if ((rfp = fopen("unix.dat", "r")) == NULL) { • 09 perror("fopen: unix.dat"); • 10 exit(1); • 11 } • 12 • 13 printf("학번 평균\n"); • while ((n=fscanf(rfp, "%d %d %d %d %d", &id,&s1,&s2,&s3,&s4)) • != EOF) { • 15 printf("%d : %d\n", id, (s1+s2+s3+s4)/4); • 16 } • 17 • 18 fclose(rfp); • 19 • 20 return 0; • 21 } # cat unix.dat 2009001 80 95 80 95 2009002 85 90 90 80 # ex2_15.out 학번 평균 2009001 : 87 2009002 : 86

  39. [예제 2-16] fprintf 함수 사용하기 ex2_16.c 01 #include <stdlib.h> 02 #include <stdio.h> 03 04 int main(void) { 05 FILE *rfp, *wfp; 06 int id, s1, s2, s3, s4, n; 07 08 if ((rfp = fopen("unix.dat", "r")) == NULL) { 09 perror("fopen: unix.dat"); 10 exit(1); 11 } 12 13 if ((wfp = fopen("unix.scr", "w")) == NULL) { 14 perror("fopen: unix.scr"); 15 exit(1); 16 } 17 18 fprintf(wfp, “ 학번 평균\n"); 19 while ((n=fscanf(rfp, "%d %d %d %d %d", &id,&s1,&s2,&s3,&s4)) != EOF) { 20 fprintf(wfp, "%d : %d\n", id, (s1+s2+s3+s4)/4); 21 } 22 23 fclose(rfp); 24 fclose(wfp); 25 26 return 0; 27 } 입출력에 형식 지정 기호 사용 # ex2_16.out # cat unix.scr 학번 평균 2009001 : 87 2009002 : 86 # cat unix.dat 2009001 80 95 80 95 2009002 85 90 90 80

  40. 파일 오프셋 이동: fseek(3) stream이 가리키는 파일에서 offset에 지정한 크기만큼 오프셋을 이동 whence는 lseek와 같은 값을 사용 fseek는 성공하면 0을 실패하면 EOF를 반환 현재 오프셋 구하기: ftell(3) 현재 오프셋을 반환 오프셋은 파일의 시작에서 현재 위치까지의 바이트 수 고수준 파일입출력 : 파일 오프셋 지정 (1) #include <stdio.h> intfseek(FILE *stream, long offset, int whence); #include <stdio.h> long ftell(FILE *stream);

  41. 처음 위치로 오프셋 이동: rewind(3) 오프셋을 파일의 시작 위치로 즉시 이동 오프셋의 저장과 이동: fsetpos(3), fgetpos(3) fgetpos : 파일의 현재 오프셋을 pos가 가리키는 영역에 저장 fsetpos : pos가 가리키는 위치로 파일 오프셋을 이동 고수준 파일입출력 : 파일 오프셋 지정 (2) #include <stdio.h> void rewind(FILE *stream); #include <stdio.h> intfsetpos(FILE *stream, const fpos_t *pos); intfgetpos(FILE *stream, fpos_t *pos);

  42. [예제 2-17] fseek 함수 사용하기 ex2_17.c • ... • 04 int main(void) { • 05 FILE *fp; • 06 int n; • 07 long cur; • 08 char buf[BUFSIZ]; • 09 • 10 if ((fp = fopen("unix.txt", "r")) == NULL) { • 11 perror("fopen: unix.txt"); • 12 exit(1); • 13 } • 14 • cur = ftell(fp); • printf("Offset cur=%d\n", (int)cur); • 17 • 18 n = fread(buf, sizeof(char), 4, fp); • 19 buf[n] = '\0'; • 20 printf("-- Read Str=%s\n", buf); • 21 • 22 fseek(fp, 1, SEEK_CUR); • 23 • 24 cur = ftell(fp); • 25 printf("Offset cur=%d\n", (int)cur); • 26 현재 오프셋 읽기 오프셋 이동

  43. [예제 2-17] fseek 함수 사용하기 27 n = fread(buf, sizeof(char), 6, fp); 28 buf[n] = '\0'; 29 printf("-- Read Str=%s\n", buf); 30 31 cur = 12; 32 fsetpos(fp, &cur); 33 34 fgetpos(fp, &cur); 35 printf("Offset cur=%d\n", (int)cur); 36 37 n = fread(buf, sizeof(char), 13, fp); 38 buf[n] = '\0'; 39 printf("-- Read Str=%s\n", buf); 40 41 fclose(fp); 42 43 return 0; 44 } 오프셋 이동 현재 오프셋 읽어서 지정 # ex2_17.out Offset cur=0 -- Read Str=Unix Offset cur=5 -- Read Str=System Offset cur=12 -- Read Str=Programming

  44. 저수준 파일 입출력의 파일 기술자와 고수준 파일 입출력의 파일 포인터는 상호 변환 가능 파일 포인터 생성: fdopen(3) 파일 기술자와 모드값을 받아 파일 포인터를 생성 파일 기술자 생성: fileno(3) 파일 포인터를 인자로 받아 파일 기술자를 반환 파일 기술자와 파일 포인터 간의 변환 #include <stdio.h> FILE *fdopen(intfildes, const char *mode); #include <stdio.h> intfileno(FILE *stream);

  45. [예제 2-18] fdopen 함수 사용하기 ex2_18.c 01 #include <fcntl.h> 02 #include <stdlib.h> 03 #include <stdio.h> 04 05 int main(void) { 06 FILE *fp; 07 intfd; 08 char str[BUFSIZ]; 09 10 fd = open("unix.txt", O_RDONLY); 11 if (fd == -1) { 12 perror("open"); 13 exit(1); 14 } 15 16 fp = fdopen(fd, "r"); 17 18 fgets(str, BUFSIZ, fp); 19 printf("Read : %s\n", str); 20 21 fclose(fp); 22 23 return 0; 24 } 저수준 파일입출력 함수로 파일 오픈 파일 포인터 생성 고수준 파일읽기 함수로 읽기 # ex2_18.out Read : Unix System Programming

  46. [예제 2-19] fileno 함수 사용하기 ex2_19.c 01 #include <unistd.h> 02 #include <fcntl.h> 03 #include <stdlib.h> 04 #include <stdio.h> 05 06 int main(void) { 07 FILE *fp; 08 intfd, n; 09 char str[BUFSIZ]; 10 11 fp = fopen("unix.txt", "r"); 12 if (fp == NULL) { 13 perror("fopen"); 14 exit(1); 15 } 16 17 fd = fileno(fp); 18 printf("fd : %d\n", fd); 19 20 n = read(fd, str, BUFSIZ); 21 str[n] = '\0'; 22 printf("Read : %s\n", str);22 23 24 close(fd); 25 26 return 0; 27 } 고수준 파일입출력 함수로 파일 오픈 파일 기술자 리턴 저수준 파일읽기 함수로 읽기 # ex2_19.out fd : 3 Read : Unix System Programming

  47. 파일명이 중복되지 않도록 임시파일명 생성 임시파일명 생성: tmpnam(3) 임시 파일명을 시스템이 알아서 생성 접두어 지정: tempnam(3) 임시파일명에 사용할 디렉토리와 접두어 지정, 접두어는 5글자까지만 지원 임시 파일 사용 (1) #include <stdio.h> char *tmpnam(char *s); #include <stdio.h> char *tempnam(const char *dir, const char *pfx); char *fname; fname = tempnam("/tmp", "hanbit");

  48. 템플릿을 지정한 임시 파일명 생성: mktemp(3) 임시파일의 템플릿을 받아 임시 파일명 생성 템플릿은 대문자 ‘X’6개로 마치도록 해야한다. 임시 파일 사용 (2) #include <stdlib.h> char *mktemp(char *template); /tmp/hanbitXXXXXX

  49. [예제 2-20] 임시 파일명 만들기 ex2_20.c 01 #include <stdio.h> 02 #include <stdlib.h> 03 #include <string.h> 04 05 int main(void) { 06 char *fname; 07 char fntmp[BUFSIZ]; 08 char template[32]; 09 10 fname = tmpnam(NULL); 11 printf("1. TMP File Name(tmpnam) : %s\n", fname); 12 13 tmpnam(fntmp); 14 printf("2. TMP File Name(tmpnam) : %s\n", fntmp); 15 16 fname = tempnam("/tmp", "hanbit"); 17 printf("3. TMP File Name(tempnam) : %s\n", fname); 18 19 strcpy(template, "/tmp/hanbitXXXXXX"); 20 fname = mktemp(template); 21 printf("4. TMP File Name(mktemp) : %s\n", fname); 22 23 return 0; 24 } # ex2_20.out 1. TMP File Name(tmpnam) : /var/tmp/aaaFUaGOe 2. TMP File Name(tmpnam) : /var/tmp/baaGUaGOe 3. TMP File Name(tempnam) : /tmp/hanbiAAAHUaGOe 4. TMP File Name(mktemp) : /tmp/hanbitIUaGOe

  50. tmpfile(3) 자동으로 w+ 모드로 열린 파일 포인터를 반환 임시 파일의 파일 포인터 생성 #include <stdio.h> FILE *tmpfile(); 01 #include <stdio.h> 02 03 int main(void) { 04 FILE *fp; 05 06 fp = tmpfile(); 07 08 fputs("unix system", fp); 09 10 fclose(fp); 11 12 return 0; 13 } 임시 파일에 출력

More Related