[제3장] 파일 사용하기

정보 | 2007/06/25 19:00

=================================================================
  * Subject : [제3장] 파일 사용하기
  * Writer: w0rm9 (research.hackerschool.org)
  * Date: 2004/01/16
=================================================================

/* 책에 나와있던 gets, puts...등의 함수들은 생략했습니다.
 * 스터디 시간에 하지 않았던 부분이라서..
 */

0x01. 저수준 파일 액세스
프로그램이 시작될 때 가지는 세 개의 파일 기술자
 0 : 표준입력
 1 : 표준출력
 2 : 표준에러

■ write
사용법)
#include <unistd.h>
size_t write(int fildes, const void *buf, size_t nbytes);
=> buf를 nbytes만큼 fildes와 관련된 파일에 기록

테스트)
[w0rm9@work FILE]$ cat write.c
#include <unistd.h>
#include <stdio.h>

int main()
{
        write(1, "wiseguys output!!\n", 18);
        write(2, "wiseguys error!!\n", 17);

        exit(0);
}
[w0rm9@work FILE]$ gcc -o write write.c
[w0rm9@work FILE]$ ./write
wiseguys output!!
wiseguys error!!

■ read
사용법)
#include <unistd.h>
size_t read(int fildes, void *buf, size_t nbytes);
=> fildes와 관련된 파일로부터 nbytes 바이트까지 데이터를 읽어서 buf에 저장

테스트)
[w0rm9@work FILE]$ cat read.c
#include <unistd.h>
#include <stdio.h>

int main()
{
        char buf[100];
        int nread;

        nread = read(0, buf, 100);
        write(1, buf , nread);
}
[w0rm9@work FILE]$ gcc -o read read.c
[w0rm9@work FILE]$ ./read
wiseguys~
wiseguys~

■ open
사용법)
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int open(const char *path, int oflags);
int open(const char *path, int oflags, mode_t mode);
=> paht를 oflags와 mode에 관련하여 연다.

□ oflags의 필수적인 파일 액세스 모드
 O_RDONLY 읽기 전용 상태로 연다.
 O_WRONLY 쓰기 전용 상태로 연다.
 O_RDWR  읽기와 쓰기 상태로 연다.
□ oflags의 선택적인 모드
 O_APPEND 파일의 마지막에 데이터를 추가한다.
 O_TRUNC  기존의 내용을 제거하고, 파일의 길이를 0으로 설정한다.
 O_CREAT  필요하다면 mode에 주저진 상태로 파일을 생성한다.
 O_EXCL  O_CREAT와 함께 사용되며, 파일이 이미 존재하면 실해할 것이다.
□ O_CREAT 플래그를 사용할때, 세 파라미터로 사용해야할 플래그
 S_IRUSR   소유자 읽기 허용
 S_IWUSR   소유자 쓰기 허용
 S_IXUSR   소유자 실행 허용
 S_IRGRP    그룹 읽기 허용
 S_IWGRP    그룹 쓰기 허용
 S_IXGRP  그룹 실행 허용
 S_IROTH  기타 읽기 허용
 S_IWOTH  기타 쓰기 허용
 S_IXOTH  기타 실행 허용

테스트)
[w0rm9@work FILE]$ cat open.c
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int main()
{
        int one, two;
        one = open("file.one", O_CREAT|O_EXCL, S_IRUSR|S_IRGRP|S_IROTH);
        if(one==-1)
                printf("exist\n");
        two = open("file.two", O_CREAT, S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);

        exit(0);
}
[w0rm9@work FILE]$ touch file.one
[w0rm9@work FILE]$ gcc -o open open.c
[w0rm9@work FILE]$ ./open
exist
[w0rm9@work FILE]$ ls -al file.*
-rw-rw-r--    1 w0rm9    w0rm9           0  1월 16 02:19 file.one
-r-xr-xr-x    1 w0rm9    w0rm9           0  1월 16 02:10 file.two

■ close
사용법)
#include <unistd.h>

int close(int fildes);
=> fildes와 파일의 관계를 정리하기 위해 close를 사용
 
■ lseek
사용법)
#include <unistd.h>
#include <sys/types.h>

off_t lseek(int fildes, off_t offset, int whence);
=> files의 읽기/쓰기 포인터를 whence를 기준으로 offset을 지정

□ whence에 올 수 있는 것들
 SEEK_SET offset은 절대 위치이다.
 SEEK_CUR offset은 현대 위치에 상대적이다.
 SEEK_END offset은 파일의 마지막에 상대적이다.

■ fstat, stat 그리고 lstat
사용법)
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

int fstat(int fildes, struct stat *buf);
int stat(const char *path, struct stat *buf);
int lstat(const char *path, struct stat *buf);
=> fstat : 파일 기술자와 관련된 파일에 대한 상태 정보를 반환
   stat : 링크가 참조하는 파일에 대한 정보를 반환
   lstat : 링크자체에 대한 정보를 반환

struct stat {
        unsigned short st_dev;  //파일이 존재하는 장치
        unsigned short __pad1;  
        unsigned long st_ino;  //파일과 관련된 inode
        unsigned short st_mode;  //파일 허용 권한과 파일 형태 정보
        unsigned short st_nlink; //파일에 대한 하드 링크의 수
        unsigned short st_uid;  //파일 소유자의 사용자 식별자
        unsigned short st_gid;  //파일 소유자의 그룹 식별자
        unsigned short st_rdev;
        unsigned short __pad2;
        unsigned long  st_size;
        unsigned long  st_blksize;
        unsigned long  st_blocks;
        unsigned long  st_atime; //마지막 액세스 시간
        unsigned long  __unused1;
        unsigned long  st_mtime; //내용에 대한 마지막 변경 시간
        unsigned long  __unused2;
        unsigned long  st_ctime; //허용 권한, 소유자, 그룹, 내용에 대한 마지막 변경 시간
        unsigned long  __unused3;
        unsigned long  __unused4;
        unsigned long  __unused5;
};

테스트)
[w0rm9@work FILE]$ cat stat.c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
int main(int argc, char **argv)
{
        int file;
        struct stat buf;

        file = open(argv[1], O_RDONLY);
        fstat(file, &buf);
        printf("fstat => uid: %d, gid: %d\n", buf.st_uid, buf.st_gid);

        stat(argv[1], &buf);
        printf("stat => uid: %d, gid: %d\n", buf.st_uid, buf.st_gid);

        lstat(argv[1], &buf);
        printf("lstat => uid: %d, gid: %d\n", buf.st_uid, buf.st_gid);
}

[w0rm9@work FILE]$ ln -s /bin/sh stat.test
[w0rm9@work FILE]$ gcc -o stat stat.c
[w0rm9@work FILE]$ ./stat stat.test
fstat => uid: 0, gid: 0
stat => uid: 0, gid: 0
lstat => uid: 519, gid: 519
[w0rm9@work FILE]$ id
uid=519(w0rm9) gid=519(w0rm9) groups=519(w0rm9)


0x02. 표준 I/O 라이브러리
프로그램이 시작될 때 열리는 세 개의 파일 스트림
 stdin : 표준입력
 stdout : 표준출력
 stderr : 표준에러

■ fopen
사용법)
#include <stdio.h>

FILE *fopen(const char *filename, const char *mode);
=> filename에 지정된 파일을 mode에 관련하여 열고 스트림에 관련시킨다.

□ mode
 "r" 또는 "rb"               읽기 전용으로 연다.
 "w" 또는 "wb"               쓰기 상태로 열고, 길이를 0으로 줄인다.
 "a" 또는 "ab"               쓰기 상태로 열고, 파일의 마지막에 추가한다.
 "r+" 또는 "rb+" 또는 "r+b"  갱신(읽기 + 쓰기) 상태로 연다.(b는 바이너리파일)
 "w+" 또는 "wb+" 또는 "w+b"  갱신 상태로 열고, 길이를 0으로 줄인다.
 "a+" 또는 "ab+" 또는 "a+b"  갱신 상태로 열고, 파일의 마지막에 추가한다.

■ fread
사용법)
#include <stdio.h>

size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
=> stream으로 부터 레코드 크기 size와 개수 nitems에 의한 지정만큼 ptr로 읽어들인다.

■ fwrite
사용법)
#include <stdio.h>

size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream);
=> ptr에 지정된 데이터 버퍼로부터 stream에 기록한다.

■ fclose
사용법)
#include <stdio.h>

int fclose(FILE *stream);

테스트)
[w0rm9@work FILE]$ cat fread.c
#include <stdio.h>

int main(int argc, char *argv[])
{
        FILE *fp1, *fp2;
        size_t nfp1;
        char buf[BUFSIZ+1];

        fp1 = fopen("fread.c", "r");
        fp2 = fopen("fwrite.test", "w");

        nfp1 = fread(buf, sizeof(char), BUFSIZ, fp1);
        fwrite(buf, sizeof(char), nfp1, fp2);

        fclose(fp1);
        fclose(fp2);
}
[w0rm9@work FILE]$ gcc -o fread fread.c
[w0rm9@work FILE]$ ./fread
[w0rm9@work FILE]$ cat fwrite.test
#include <stdio.h>

int main(int argc, char *argv[])
{
        FILE *fp1, *fp2;
        size_t nfp1;
        char buf[BUFSIZ+1];

        fp1 = fopen("fread.c", "r");
        fp2 = fopen("fwrite.test", "w");

        nfp1 = fread(buf, sizeof(char), BUFSIZ, fp1);
        fwrite(buf, sizeof(char), nfp1, fp2);

        fclose(fp1);
        fclose(fp2);
}  

■ fflush
사용법)
#include <stdio.h>

int fflush(FILE *stream);
=> 스트림을 강제 방출한다.

■ perror
사용법)
#include <stdio.h>

void perror(const char *s);

테스트)
[w0rm9@work FILE]$ cat perror.c
#include <errno.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
        FILE *fp;
        fp = fopen("xxxxx", "r");
        if(!fp) perror("오 노우..");
}

[w0rm9@work FILE]$ gcc -o perror perror.c
[w0rm9@work FILE]$ ./perror
오 노우..: No such file or directory


__eof__

Trackback Address :: http://badnom.com/trackback/285 관련글 쓰기
Name
Password
Homepage
Secret
< PREV |  1  |  ...  792  |  793  |  794  |  795  |  796  |  797  |  798  |  799  |  800  |  ...  1016  |  NEXT >