2018년 10월 30일 화요일

[Linux, Unix] File 입출력 예제

이번시간에는 file입출력 예제들을 살펴보도록 하겠습니다.


 1. test.txt파일의 내용을 test2.txt파일에 복사 (없으면 생성)  


 ▷ 실행코드
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4. #include<fcntl.h>
  5. #define FILE_SIZE       1024
  6. int main(){
  7.         int fd, fd2;
  8.         char * readData = (char *)malloc(sizeof(char) * FILE_SIZE);
  9.         memset(readData, 0, 1024);
  10.         if( ( fd = open("test.txt", O_RDONLY)) < 0){
  11.                 printf("open() error!\n");
  12.                 exit(1);
  13.         }
  14.         read(fd, readData, FILE_SIZE);
  15.         if( ( fd2 = open("test2.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0){
  16.                 printf("fd2 open() error\n");
  17.                 exit(1);
  18.         }
  19.         write(fd2, readData, strlen(readData));
  20.         close(fd);
  21.         close(fd2);
  22.         free(readData);
  23.         return 0;
  24. }


 ▶ 실행결과











: test2.txt파일을 생성하여 test.txt의 파일내용을 복사하여 붙여넣음.






2. cat명령어 구현하기 (명령어 인자로 '>'와 '>>'를 사용하기)


 ▷ 실행코드
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<fcntl.h>
  5. #define FILE_SIZE       1024
  6. int main(int argc, char * argv[]){
  7.         int fd;
  8.         char * readData = (char *)malloc(sizeof(char) * FILE_SIZE);
  9.         char * writeData = (char *)malloc(sizeof(char) * FILE_SIZE);
  10.         if(argc == 2) // (simple) file print
  11.         {
  12.                 if( ( fd = open(argv[1], O_RDONLY)) < 0){ // not exists files
  13.                         printf("File not exists\n");
  14.                         exit(1);
  15.                 }
  16.                 read(fd, readData, FILE_SIZE);
  17.                 printf("%s print\n", argv[1]);
  18.                 printf("%s\n", readData);
  19.                 close(fd);
  20.                 free(readData);
  21.         }
  22.         else if(argc > 2) // parameteres exist(append OR overwrite)
  23.         {
  24.                 if(strcmp(argv[1], ">") == 0) // overwrite.
  25.                         fd = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0644);
  26.                 else if(strcmp(argv[1], ">>") == 0) // append.
  27.                         fd = open(argv[2], O_CREAT | O_WRONLY | O_APPEND, 0644);
  28.                 else
  29.                 {
  30.                         printf("%s don`t parameters\n", argv[1]);
  31.                         exit(1);
  32.                 }
  33.                         scanf("%s", writeData);
  34.                         write(fd, writeData, strlen(writeData));
  35.                         close(fd);
  36.                         free(writeData);
  37.         }
  38.         return 0;
  39. }


 ▶ 실행결과

1) cat명령어 (명령행 인자로 > 옵션 사용)




2) cat명렁어 (명령행 인자로 >> 옵션 사용)




: cat명령어와 동일한 옵션을 사용하였다.
1) 파일내용 출력 (기본 실행)
2) >옵션으로 파일내용 덮어쓰기(overwrite)
3) >>옵션으로 파일내용 덧붙이기(append)






3. dup사용 (파일 디스크립터 복사)

 ▷ 실행코드
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<fcntl.h>
  4. int main(){
  5.         int fd, copy_fd;
  6.         if( (fd = open("test.txt", O_RDONLY)) < 0){
  7.                 printf("open(0 error\n");
  8.                 exit(1);
  9.         }
  10.         copy_fd = dup(fd);
  11.         printf("fd : %d\n", fd);
  12.         printf("copy_fd : %d\n", copy_fd);
  13.         close(fd);
  14.         close(copy_fd);
  15.         return 0;
  16. }

 ▶ 실행결과







: fd는 3번, dup()로 복사된 파일 디스크립터 copy_fd는 4번을 가진다.
파일 디스크립터는 0부터 차례대로 채워서 생성이 되는데, 0~2는 기본 파일 디스크립터에 해당하므로 3번과 4번을 차례대로 부여하였다.






4. dup사용 (복사된 디스크립터로 출력)

 - 그렇다면 복사된 파일 디스크립터로 출력이 가능한지 살펴보자.

 ▷ 실행코드
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4. #include<fcntl.h>
  5. int main(){
  6.         int fd, copy_fd;
  7.         char * readData = (char *)malloc(sizeof(char) * 1024);
  8.         memset(readData, 0, 1024);
  9.         if( ( fd = open("test.txt", O_RDONLY)) < 0){
  10.                 printf("open() error\n");
  11.                 exit(1);
  12.         }
  13.         copy_fd = dup(fd);
  14.         read(copy_fd, readData, 1024);
  15.         printf("fd : %d\n", fd);
  16.         printf("copy_fd : %d\n", copy_fd);
  17.         printf("%s\n", readData);
  18.         close(fd);
  19.         close(copy_fd);
  20.         free(readData);
  21.         return 0;
  22. }

 ▶ 실행결과










: 기존의 디스크립터를 O_RDONLY로 읽기전용으로 파일을 open한 뒤 복사한 copy_fd로 read()하여 파일 내용을 읽어온 뒤 출력하는 예제이다.
결과를 보니, 복사한 디스크립터도 기존 디스크립터와 같은 기능을 수행할 수 있다.







5. dup사용 (기존 파일 디스크립터 삭제 후 디스크립터 확인하기)

 - 기존 파일디스크립터를 삭제하고 복제된 파일 디스크립터는 그대로 사용이 가능한지 살펴보자.

 ▷ 실행코드
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4. #include<fcntl.h>
  5. int main(){
  6.         int fd, copy_fd;
  7.         char * writeData = "dup Test";
  8.         char * readData = (char *)malloc(sizeof(char) * 1024);
  9.         memset(readData, 0, 1024);
  10.         fd = open("anyFile.txt", O_CREAT | O_RDWR | O_TRUNC, 0644);
  11.         copy_fd = dup(fd);
  12.         printf("dup(fd)\n");
  13.         printf("fd : %d\n", fd);
  14.         printf("copy_fd : %d\n", copy_fd);
  15.         close(fd);
  16.         printf("fd close");
  17.         printf("fd : %d\n", fd);
  18.         printf("copy_fd : %d\n", copy_fd);
  19.         write(copy_fd, writeData, strlen(writeData));
  20.         lseek(copy_fd, 0, SEEK_SET);
  21.         read(copy_fd, readData, 1024);
  22.         printf("%s\n", readData);
  23.         close(copy_fd);
  24.         free(readData);
  25.         return 0;
  26. }

 ▶ 실행결과








: 파일 디스크립터 복사할때 기능도 복사되었고 기존 파일디스크립터에 의존성을 갖지 않는다. 중간에 lseek함수를 통해서 다시 파일을 읽을때 처음부터 읽을 수 있도록 만들었다.

write를 사용하면 파일이 write()함수가 실행된 만큼 이동하게 된다. 즉, 파일을 write한 부분부터 가리키게 된다. 그래서 read하게되면 아무값도 출력되지 않는다.
그러므로 lseek(파일디스크립터, 시작할위치, 앞이나 뒤 부분); 를 통해서 read할 파일 위치를 명시해야 한다.



6. dup2사용 (표준에러를 파일로 출력하기.)


 ▷ 실행코드
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<fcntl.h>
  4. int main(){
  5.         int fd, fd2;
  6.         fd = open("errorLog.txt", O_CREAT | O_RDWR | O_TRUNC, 0644);
  7.         dup2(fd, 2);
  8.         if( (fd2 = open("anyfile.txt", O_RDONLY)) < 0){
  9.                 perror("occurs error\n");
  10.         }
  11.         close(fd);
  12.         return 0;
  13. }

 ▶ 실행결과






: dup2를 사용해서 표준에러 출력(파일 디스크립터로 2번)을 파일로 출력하였다.
 (anyfile.txt라는 존재하지 않는 파일로 고의로 에러를 발생시킨것임.)



7. dup2의 사용 (파일 디스크립터 값을 확인해보자.)


 ▷ 실행코드
  1. #include<stdio.h>
  2. #include<fcntl.h>
  3. int main(){
  4.         int fd;
  5.         fd = open("test.txt", O_CREAT | O_RDONLY, 0644);
  6.         dup2(fd, 2);
  7.         printf("fd : %d\n", fd);
  8.         return 0;
  9. }


 ▶ 실행결과






: 역시 새로운 파일 디스크립터 번호를 할당받는다.




댓글 없음:

댓글 쓰기

[Java] N-I/O(Non-Blocking) 파일 읽기 쓰기 - GatheringByteChannel, ScatteringByteChannel, ByteBuffer 사용.

우리는 지금까지 다음과 같이 살펴보았다. 1.  InputStream / OutputStream : 입, 출력 스트림을 바이트로 처리하여 읽기, 쓰기. 2.  FileInputStream / FileOutputStream : 입, 출력 스트림을 ...