0w0

저수준 파일 입출력 본문

Coding/System Programming

저수준 파일 입출력

0w0 2016. 10. 6. 20:37
728x90
반응형

저수준 파일 입출력 


저수준 파일 입출력은 유닉스 커널의 시스템 호출을 사용하여 파일 입출력을 수행한다.


파일 지시자 : int fd            (파일 기술자)

특징 :     훨씬 빠르다.

바이트 단위로 읽고 쓴다.

특수 파일에 대한 접근이 가능하다.



파일 열기 : open(2)


open 함수는 파일 열기에 성공하면 파일 기술자를 리턴한다. 파일 열기에 실패하면 -1을 리턴하고, 외부 변수 errno에 실패한 이유를 설명하는 오류 코드를 저장한다. 이 오류 코드를 perror 함수로 출력하면 해당 메시지를 확인할 수 있다.


함수원형

#include<sys/types.h>

#include<sys/stat.h> 

#include<fcntl.h>    //file control의 약자


int open(const char *path, int oflag [, mode_t mod]);    

//path : 열려는 파일이 있는 경로

//oflag : 파일 상태 플래그

//mod : 접근권한



[3210w0@localhost ch02]$ man -s 2 open


oflag

O_RDONLY

파일을 읽기 전용으로 연다

0x0001

O_WRONLY

파일을 쓰기 전용으로 연다

0x0002

O_RDWR

파일을 읽기/쓰기용으로 연다

0x0004

O_CREAT

파일이 없으면 생성, 파일을 생성할 권한은 당연히 있어야 한다.

0x0100

O_TRUNC

파일을 생성할 때 이미 있는 파일이고, 쓰기 옵션으로 열었으면 내용을 모두 지우고 파일의 길이를 0으로 변경한다.

0x0200

O_EXCL

O_CREAT과 함께 사용할 경우 기존에 없는 파일이면 생성하지만, 이미 있으면 파일을 생성하지 않고 오류 메시지를 출력한다.

0x0400

O_APPEND

이 옵션을 지정하면 파일의 맨 끝에 내용을 추가한다.

0x0800

O_TEXT

화일을 텍스트 형식으로 연다.

0x4000

O_BINARY

화일을 이진 형식으로 연다.

0x8000



플래그를 OR(|) 연산자로 연결해 지정할 수 있다. 
ex)
쓰기 전용으로 열 때, 이미 파일이 있는 경우 : O_WRONLY | O_TRUNC
쓰기 전용으로 열 때, 파일이 없는 경우 : O_WRONY | O_CREAT | O_TRUNC
읽기/쓰기/추가용으로 열 때  : O_RDWR | O_APPEND



mode

mode는 파일의 접근 권한을 설정하는 것으로, O_CREAT 플래그를 지정해 파일을 생성할 때만 사용한다. 


S_IRWXU  00700 user (file owner) has read, write, and execute permission


              S_IRUSR  00400 user has read permission


              S_IWUSR  00200 user has write permission


              S_IXUSR  00100 user has execute permission


              S_IRWXG  00070 group has read, write, and execute permission


              S_IRGRP  00040 group has read permission


              S_IWGRP  00020 group has write permission


              S_IXGRP  00010 group has execute permission


              S_IRWXO  00007 others have read, write, and execute permission


              S_IROTH  00004 others have read permission


              S_IWOTH  00002 others have write permission


              S_IXOTH  00001 others have execute permission


              According  to  POSIX,  the  effect  when  other bits are set in mode is unspecified.  On

              Linux, the following bits are also honored in mode:


              S_ISUID  0004000 set-user-ID bit


              S_ISGID  0002000 set-group-ID bit (see stat(2))


              S_ISVTX  0001000 sticky bit (see stat(2))






파일 생성 : creat(2)


creat 함수로 파일을 생성하면 파일 기술자가 리턴되므로, 별도로 open 함수를 호출해 파일을 열 필요가 없다.

creat 함수는 open 함수와 달리 옵션을 지정하는 부분이 없다.


함수원형

#include<sys/types.h>

#include<sys/stat.h>  

#include<fcntl.h>    //file control의 약자


int creat(const char *path, mode_t mode);

//path : 파일을 생성할 경로

//mod : 접근 권한



[3210w0@localhost ch02]$ man -s 2 creat

아래 creat함수와 open함수는 같은 의미다.
creat(path, mode);
open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);






파일 닫기 : close(2)


creat 함수로 파일을 생성하면 파일 기술자가 리턴되므로, 별도로 open 함수를 호출해 파일을 열 필요가 없다.

creat 함수는 open 함수와 달리 옵션을 지정하는 부분이 없다.


함수원형

#include<unistd.h>


int close(int fildes);

//fildes : 파일 기술자



[3210w0@localhost ch02]$ man -s 2 creat

파일을 닫는 데는 close 함수를 사용한다. 파일 입출력 작업을 모두 완료하면 반드시 파일을 닫아야 한다.
한 프로세스가 열 수 있는 파일의 개수에 제한이 있으므로, 제대로 닫지 않으면 최대 허용 개수를 초과해 더 이상 파일을 열지 못할 수 있다.

close함수는 파일을 성공적으로 닫으면 0을 리턴한다. 파일 닫기에 실패하면 -1을 리턴하고, 오류 코드를 외부 변수 errno에 저장한다.

 //새 파일 생성하기
소스!!


#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<unistd.h>

#include<stdlib.h>

#include<stdio.h>



int main(void){

        int fd;

        mode_t mode;


        mode=S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;

//파일의 접근 권한을 OR연산으로 지정한다. 


        fd=open("unix.txt", O_CREAT, mode);

//unix.txt파일을 12행에서 지정한 권한(0644)으로 생성

        if(fd==-1){

                perror("Creat");

                exit(1);

        }


        close(fd);


        return 0;

}




결과!!

[3210w0@localhost ex2_1_directory]$ ./ex2_1

[3210w0@localhost ex2_1_directory]$ ll

합계 16

-rwxrwxr-x. 1 3210w0 3210w0 8784 10월  6 22:02 ex2_1

-rw-rw-r--. 1 3210w0 3210w0  529 10월  6 22:02 ex2_1.c

-rw-r--r--. 1 3210w0 3210w0    0 10월  6 22:02 unix.txt

[3210w0@localhost ex2_1_directory]$ 





 //O_EXCL 플래그 사용하기

소스!!

 //O_EXCL 플래그 사용하기

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<unistd.h>

#include<stdlib.h>

#include<stdio.h>



int main(void){

        int fd;


        fd=open("unix.txt", O_CREAT | O_EXCL, 0644);


        if(fd==-1){

                perror("Creat");

                exit(1);

        }


        close(fd);


        return 0;

}




결과!!

[3210w0@localhost ex2_2_directory]$ gcc -o ex2_2 ex2_2.c 

[3210w0@localhost ex2_2_directory]$ ll

합계 16

-rwxrwxr-x. 1 3210w0 3210w0 8784 10월  6 22:07 ex2_2

-rw-rw-r--. 1 3210w0 3210w0  382 10월  6 22:07 ex2_2.c

[3210w0@localhost ex2_2_directory]$ ./ex2_2 

[3210w0@localhost ex2_2_directory]$ ll

합계 16

-rwxrwxr-x. 1 3210w0 3210w0 8784 10월  6 22:07 ex2_2

-rw-rw-r--. 1 3ㅋ210w0 3210w0  382 10월  6 22:07 ex2_2.c

-rw-r--r--. 1 3210w0 3210w0    0 10월  6 22:07 unix.txt

[3210w0@localhost ex2_2_directory]$ ./ex2_2 

Creat: File exists

[3210w0@localhost ex2_2_directory]$ rm unix.txt 

[3210w0@localhost ex2_2_directory]$ ./ex2_2 

[3210w0@localhost ex2_2_directory]$ ll

합계 16

-rwxrwxr-x. 1 3210w0 3210w0 8784 10월  6 22:07 ex2_2

-rw-rw-r--. 1 3210w0 3210w0  382 10월  6 22:07 ex2_2.c

-rw-r--r--. 1 3210w0 3210w0    0 10월  6 22:08 unix.txt

[3210w0@localhost ex2_2_directory]$ 




파일 기술자 할당하기

소스!!

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<unistd.h>

#include<stdlib.h>

#include<stdio.h>



int main(void){

        int fd;


        close(0);

//0번 파일 기술자를 닫는다.

fd=open("unix.txt", O_RDWR);

//남아 있는 파일 기술자 중 가장 작은 숫자가 0이므로 unix.txt파일을 가리키는 파일 기술자는 0이 된다.


if(fd==-1){

perror("Excl");

exit(1);

}

printf("unix.txt : fd=%d\n",fd);

        close(fd);


        return 0;

}





결과!!

3210w0@localhost ex2_3_directory]$ ./ex2_3 

unix.txt : fd=0

[3210w0@localhost ex2_3_directory]$ ll

total 16

-rwxrwxr-x. 1 3210w0 3210w0 8832 Oct 11 11:53 ex2_3

-rw-rw-r--. 1 3210w0 3210w0  513 Oct 11 11:53 ex2_3.c

-rw-rw-r--. 1 3210w0 3210w0    0 Oct 11 11:54 unix.txt

[3210w0@localhost ex2_3_directory]$ 










파일 읽기 : read(2)


read와 write 함수의 리턴값의 데이터형인 ssize_t는 <sys/types.h> 파일에 int(환경에 따라 long)로 정의되어 있다.


함수원형

#include<unistd.h>


ssize_t read(int fildes, void *buf, size_t nbytes);

//filders : 파일 기술자

//buf : 바이트를 저장할 메모리 영역의 시작 주소

//nbytes : 읽어올 바이트 수


read 함수는 파일 기술자가 가리키는 파일에서 nbytes로 자정한 크기만큼 바이트를 읽어서 buf로 지정한 메모리 영역에 저장한다. 
read 함수는 실제로 읽어온 바이트 수를 리턴하며, 오류가 발생하면 -1을 리턴한다. 만일 리턴값이 0이면 파일의 끝에 도달해 더 이상 읽을 내용이 없음을 의미한다.
파일을 열면 읽어올 위치를 나타내는 오프셋이 파일의 시작을 가리키지만, read 함수를 실행할 때마다 읽어온 크기만큼 오프셋이 이동해 다음 읽어올 위치를 가리킨다. 이 함수는 파일에 저장된 데이터가 텍스트든 이미지든 상관없이 무조건 바이트 단위로 읽어온다. 읽어온 데이터를 종류에 따라 처리하는 작업은 순전히 프로그래머의 몫이다.
``
[3210w0@localhost ch02]$ man -s 2 read


소스!!

//파일 읽기

#include<fcntl.h>

#include<unistd.h>

#include<stdlib.h>

#include<stdio.h>



int main(void){

        int fd,n;

char buf[10];


fd=open("unix.txt", O_RDONLY);

//unix.txt파일을 읽기 전용으로 연다.


if(fd==-1){

perror("Open");

exit(1);

}


n=read(fd,buf,6);

//6바이트를 읽어 buf에 저장하고 read함수의 리턴값을 저장한다.

//(출력 결과를 보면 6임을 알 수 있다.)


if(n==-1){

perror("Read");

exit(1);

}

buf[n]='\0';

//read 함수는 읽어온 데이터의 끝에 자동으로 널을 추가하지 않기 때문에 buf에 널 문자('\0')을 추가한다.

//buf를 문자열로 출력하려면 널을 추가해야 한다.

printf("n=%d, buf=%s\n",n,buf);

//unix.txt 파일에서 읽어온 바이트 수와 buf의 내용을 출력한다.

//(실행 결과를 보면 unix.txt 파일의 처음 여섯 바이트를 읽어왔음을 알 수 있다.)

        close(fd);


        return 0;

}




결과!!

[3210w0@localhost ex2_4_directory]$ gcc -o ex2_4 ex2_4.c 

[3210w0@localhost ex2_4_directory]$ ./ex2_4 

Open: No such file or directory

[3210w0@localhost ex2_4_directory]$ cat > unix.txt

asdf

^C

[3210w0@localhost ex2_4_directory]$ 

[3210w0@localhost ex2_4_directory]$ ./ex2_4 

n=5, buf=asdf








파일 쓰기 : write(2)


read와 write 함수의 리턴값의 데이터형인 ssize_t는 <sys/types.h> 파일에 int(환경에 따라 long)로 정의되어 있다.


함수원형

#include<unistd.h>


ssize_t write(int fildoes, const void *buf, size_t nbytes);

//filders : 파일 기술자

//buf : 파일에 기록할 데이터를 저장한 메모리 영역

//nbytes : buf의 크기(기록할 데이터의 적기)


파일 기술자는 쓰기를 수행할 파일을 가리키고, buf는 파일에 기록할 데이터를 저장하고 있는 메모리 영역을 가리킨다.
``
[3210w0@localhost ch02]$ man -s 2 write


소스!!

//파일 읽고 쓰기    ex2_5.c

#include<fcntl.h>

#include<unistd.h>

#include<stdlib.h>

#include<stdio.h>


int main(){

int rfd, wfd, n;

char buf[10];


rfd=open("unix.txt", O_RDONLY);            


if(rfd==-1){

perror("Open unix.txt");

exit(1);

}


wfd=open("unix.bak", O_CREAT | O_WRONLY | O_TRUNC, 0644);

//unix.bak 파일을 쓰기 전용으로 생성하며, 기존 파일이 있을 경우 내용을 비운다.


if(wfd==-1){

perror("Open unix.bak");

exit(1);

}


while((n=read(rfd, buf, 6))>0)    //read 함수가 리턴한 값이 buf에 저장된 데이터의 크기므로, 

if(write(wfd,buf,n)!=n)     //이를 23행에서 write 함수의 세번째 인자로 사용할 수 있다. 

perror("Write");      //write 함수의 리턴값이 출력할 데이터의 크기인 n과 다르면 쓰기 동작에 문제가 있다는 의미

//while 문을 사용해 unix.txt 파일을 6 바이트씩 읽고 출력한다.


if(n==-1) 

perror("Read");


close(rfd);

close(wfd);


return 0;


}

//실행 결과  unix,.bak 파일이 생성되고 데이터가 저장되었다. 즉, unix.txt 파일이 unix.bak 파일로 복사된 것이다.




결과!!


[3210w0@localhost ex2_5_directory]$ ll

total 16

-rwxrwxr-x. 1 3210w0 3210w0 8880 Oct  7 10:23 ex2_5

-rw-rw-r--. 1 3210w0 3210w0  482 Oct  7 10:32 ex2_5.c

[3210w0@localhost ex2_5_directory]$ ./ex2_5 

Open unix.txt: No such file or directory

[3210w0@localhost ex2_5_directory]$ gcc -o ./ex2_5 ./ex2_5.c

[3210w0@localhost ex2_5_directory]$ ll

total 16

-rwxrwxr-x. 1 3210w0 3210w0 8880 Oct  7 10:35 ex2_5

-rw-rw-r--. 1 3210w0 3210w0  486 Oct  7 10:35 ex2_5.c

[3210w0@localhost ex2_5_directory]$ cat > unix.txt

asdf

^C

[3210w0@localhost ex2_5_directory]$ 

[3210w0@localhost ex2_5_directory]$ ./ex2_5 

[3210w0@localhost ex2_5_directory]$ ll

total 24

-rwxrwxr-x. 1 3210w0 3210w0 8880 Oct  7 10:35 ex2_5

-rw-rw-r--. 1 3210w0 3210w0  486 Oct  7 10:35 ex2_5.c

-rw-r--r--. 1 3210w0 3210w0    5 Oct  7 10:35 unix.bak

-rw-rw-r--. 1 3210w0 3210w0    5 Oct  7 10:35 unix.txt









파일 오프셋 위치 지정 : lseek(2)


파일의 내용을 읽거나 쓰면 현재 읽을 위치나 쓸 위치를 알려주는 오프셋(offeset)이 자동으로 변경된다.

한 파일에서 파일 오프셋은 오직 하나다. 다시 말해, 파일을 읽기/쓰기 모드로 열었을 때 파일 읽기 오프셋과 쓰기 오프셋이 별도로 있는 것이 아니므로 주의해야 한다.


오프셋을 원하는 위치로 바꾸고, 위치를 확인하려면 lseek 함수를 사용한다.


함수원형

#include<sys/types.h>

#include<unistd.h>


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

//fildes : 파일 기술자

//offset : 이동할 오프셋 위치

//whence : 오프셋의 기준 위치


[3210w0@localhost ch02]$ man -s 2 lseek

오프셋의 기준 위치를 나타내는 whence 값

 값

설명 

SEEK_SET 

파일의 시작 기준 

SEEK_CUR 

현재 위치 기준 

SEEK_END 

파일의 끝 기준 


ex)

lseek(fd, 5, SEEK_SET)             (파일의 시작에서 5번째 위치로 이동)

lseek(fd, 0, SEEK_END)            (파일의 끝에서 0번째므로 파일의 끝으로 이동)



반대 방향으로 오프셋을 이동하려면 offset 값을 음수로 지정하면 된다. 
lseek 함수는 실행에 성고하면 새로운 오프셋을 리턴하고, 실패하면 -1을 리턴한다.
lseek 함수 리턴값의 데이터형인 off_t는 <sys/types.h> 파일에 long으로 정의되어 있다.


소스!!

//파일 오프셋 사용하기

#include<sys/types.h>

#include<fcntl.h>

#include<unistd.h>

#include<stdlib.h>

#include<stdio.h>


int main(void){

int fd, n;

off_t start, cur;

char buf[256];


fd=open("unix.txt", O_RDONLY);

//unix.txt 파일을 읽기 전용으로 연다.

if(fd==-1){

perror("Open unix.txt");

exit(1);

}


start=lseek(fd, 0, SEEK_CUR);

//파일의 현재 위치를 파악해보면 오프셋이 0임을 알 수 있다.

n=read(fd, buf, 255);

buf[n]='\0';

printf("Offset start=%d, Read Str=%s, n=%d\n", (int)start, buf, n);

cur=lseek(fd, 0, SEEK_CUR);

//데이터를 읽은 후 현재 위치를 확인한다(이 예제에서는 오프셋이 start+n 위치로 이동한다.)

printf("Offset cur=%d\n", (int)cur);

start=lseek(fd, 5, SEEK_SET);

n=read(fd, buf, 255);

//파일의 시작 기준으로 오프셋이 5인 위치로 이동한 후 데이터를 읽는다.

buf[n]='\0';

printf("Offset start=%d, Read Str=%s",(int)start, buf);


close(fd);


return 0;

}


//실행 결과를 보면 오프셋의 위치에 따라 읽어온 데이터가 다름을 알 수 있다.




결과!!

[3210w0@localhost ex2_6_directory]$ gcc -o ex2_6 ex2_6.c 

l[3210w0@localhost ex2_6_directory]$ ll

합계 16

-rwxrwxr-x. 1 3210w0 3210w0 8936 10월  8 07:09 ex2_6

-rw-rw-r--. 1 3210w0 3210w0 1067 10월  8 07:09 ex2_6.c

[3210w0@localhost ex2_6_directory]$ ./ex2_6 

Open unix.txt: No such file or directory

[3210w0@localhost ex2_6_directory]$ cat > unix.txt

Unix ~~ 

^C

[3210w0@localhost ex2_6_directory]$ 

[3210w0@localhost ex2_6_directory]$ ./ex2_6 

Offset start=0, Read Str=Unix ~~

, n=8

Offset cur=8

Offset start=5, Read Str=~~







파일 기술자 복사하기 : dup(2)


파일을 열려면 파일 기술자가 할당된다. 

이 파일 기술자를 복사해 같은 파일을 가리키는 두 번째 파일 기술자를 생성할 수 있다.

오프셋을 원하는 위치로 바꾸고, 위치를 확인하려면 lseek 함수를 사용한다.


함수원형

#include<unistd.h>


int dup(int fildes);

//fildes : 파일 기술자


[3210w0@localhost ch02]$ man -s 2 dup

dup 함수는 기존 파일 기술자를 인자로 받아 새로운 파일 기술자를 리턴한다.(복사)
새로 할당되는 파일 기술자는 현재 할당할 수 있는 파일 기술자 중 가장 작은 값으로 자동 할당된다. 파일 기술자의 복사는 입출력 방향 전환에서 많이 사용한다. 출력 방향을 표준 출력에서 파일로 전환하는 예제를 보겠다.


소스!!

//파일 기술자 복사하기

#include<fcntl.h>

#include<unistd.h>

#include<stdlib.h>

#include<stdio.h>


int main(void){

int fd, fd1;


fd=open("tmp.aaa", O_CREAT | O_WRONLY | O_TRUNC, 0644);


if(fd==-1){

perror("Create tmp.aaa");

exit(1);

}

close(1);

//1번 파일 기술자(표준 출력)를 닫는다.

fd1=dup(fd);

/*dup(fd)를 실행하면 파일 기술자 fd가 가리키는 파일에 새로운 파일 기술자가 지정된다.

15행에서 1번을 닫았기 때문에 현재 가장 작은 값은 1이고, 이 값이 새로운 파일 기술자로 할당된다.*/

printf("DUP FD=%d\n", fd1);

printf("Standard Output Redirection\n");

//현재 1번 파일 기술자가 가리키는 파일인 tmp.aaa로 출력된다.

close(fd);

return 0;

}




결과!!

[3210w0@localhost ex2_7_directory]$ ll

합계 20

-rwxrwxr-x. 1 3210w0 3210w0 8928 10월  8 07:58 ex2_7

-rw-rw-r--. 1 3210w0 3210w0  737 10월  8 07:58 ex2_7.c

-rw-r--r--. 1 3210w0 3210w0   37 10월  8 07:58 tmp.aaa

[3210w0@localhost ex2_7_directory]$ cat tmp.aaa 

DUP FD=1

Standard Output Redirection




파일 기술자 복사하기 : dup2(3)


dup2 함수는 새로운 파일 기술자를 지정할 수 있게 해준다.

dup2 함수는 파일 기술자 fildes를 fildes2로 복사한다.


함수원형

#include<unistd.h>


int dup2(int fildes, int fildes2);

//fildes : 파일 기술자

//fildes2 : 파일 기술자를 복사할 곳


[3210w0@localhost ch02]$ man -s 3 dup2



소스!!

#include<fcntl.h>

#include<unistd.h>

#include<stdlib.h>

#include<stdio.h>


int main(void){

int fd;


fd=open("tmp.bbb", O_CREAT | O_WRONLY | O_TRUNC, 0644);


if(fd==-1){

perror("Create tmp.bbb");

exit(1);

}

dup2(fd, 1);

/*dup2 함수를 사용해 기존 파일 기술자(fd)를 1번 파일 기술자로 복사한다. 이제 1번 파일 기술자로 출력하면 더이상 표준 출력(화면)이 아닌 fd가 가리키는 파일로 출력한다.*/

printf("DUP2 : Standard Output Redirection\n ");


close(fd);

return 0;

}




결과!!

[3210w0@localhost ex2_8_directory]$ ll

합계 20

-rwxrwxr-x. 1 3210w0 3210w0 8880 10월  8 08:07 ex2_8

-rw-rw-r--. 1 3210w0 3210w0  538 10월  8 08:07 ex2_8.c

-rw-r--r--. 1 3210w0 3210w0   36 10월  8 08:07 tmp.bbb

DUP2 : Standard Output Redirection








파일 기술자 복사하기 : fcntl(2)


fcntl 함수를 사용하면 파일을 열 때 설정한 플래그들을 조정할 수 있다.


함수원형

#Include<sys/types.h>

#include<unistd.h>

#include<fcntl.h>


int fcntl(int fildes, int cmd, /* arg*/ ...);

//fildes : 파일 기술자

//cmd : 명령

//arg : cmd에 따라 필요시 지정하는 인자들


[3210w0@localhost ch02]$ man -s 2 fcntl

 F_GETFL

 상태 플래그 정보를 읽어온다.

 F_SETFL 

상태 플래그 정보를 설정한다. 설정할 수 있는 플래그는 대부분 openㅏㅁ수에서 지정하는 플래그다.





소스!!

//fcntl 함수로 파일 기술자 제어하기

#include<sys/types.h>

#include<fcntl.h>

#include<unistd.h>

#include<stdlib.h>

#include<stdio.h>


int main(void){

int fd,flags;


fd=open("unix.txt", O_RDWR);

//unix.txt 파일을 읽기/쓰기용으로 연다.


if(fd==-1){

perror("open");

exit(1);

}

if((flags=fcntl(fd, F_GETFL))==-1){

//F_GETFL 명령을 설정해 fcntl 함수를 호출하면 현재 설정된 플래그 값이 리턴된다.

perror("fcntl");

exit(1);

}


flags |=O_APPEND;

//리턴된 플래그 값에 변경할 플래그를 OR로 연결해 새로운 플래그로 저장한다.


if(fcntl(fd, F_SETFL, flags)==-1){

//저장된 플래그를 F_SETFL명령으로 설정해 fcntl 함수를 호출하면 

//기존 플래그가 새로운 플래그로 변경된다.

perror("fcntl");

exit(1);

}


if(write(fd, "Hanbit Media", 12)!=12) perror("write");

//파일의 설정을 O_APPEND로 변경했기 때문에 파일에 출력하면 내용이 파일의 끝부분에 추가된다.

close(fd);

return 0;

}




결과!!

[3210w0@localhost ex2_9_directory]$ cat > unix.txt

^C

[3210w0@localhost ex2_9_directory]$ 

[3210w0@localhost ex2_9_directory]$ ./ex2_9 


[3210w0@localhost ex2_9_directory]$ cat unix.txt 

Hanbit Media[3210w0@localhost ex2_9_directory]$ 

[3210w0@localhost ex2_9_directory]$ 







파일 삭제 : unlink(2)


파일을 삭제하려면 unlink(2)함수를 사용한다.


함수원형

#include<unistd.h>


int unlink(const char *path);

//path : 삭제할 파일의 경로


[3210w0@localhost ch02]$ man -s 2 unlink

unlink 함수는 path에 지정한 파일의 inode에서 링크 수를 감소시킨다. 링크 수가 0이 되면 path에 지정한 파일이 삭제된다. 

unlink와 같은 기능을 하는 함수로 remove(3)가 있다.
#include<stdio.h>
int remove(const char *path);
//path : 경로



소스!!

//unlink 함수로 파일 삭제하기

#include<unistd.h>

#include<stdio.h>

#include<stdlib.h>



int main(){


int cnt;


cnt=unlink("tmp.aaa");

//unlink 함수를 이용해 tmp.aaa 파일을 삭제한다.


if(cnt==-1){

perror("Unlink tmp.aaa");

exit(1);

}


printf("Unlink tmp.aaa success!!!\n");

//파일을 성공적으로 삭제하며 문자열을 메시지로 출력한다.


return 0;

}




결과!!

[3210w0@localhost ex2_10_directory]$ cat > tmp.aaa

^C

[3210w0@localhost ex2_10_directory]$ 

[3210w0@localhost ex2_10_directory]$ ./ex2_10 

Unlink tmp.aaa success!!!

[3210w0@localhost ex2_10_directory]$ ll

합계 16

-rwxrwxr-x. 1 3210w0 3210w0 8784 10월 10 07:22 ex2_10

-rw-rw-r--. 1 3210w0 3210w0  362 10월 10 07:22 ex2_10.c

[3210w0@localhost ex2_10_directory]$ 







파일과 디스크 동기화 함수 : fsync(3)


파일을 삭제하려면 unlink(2)함수를 사용한다.


함수원형

#include<unistd.h>


int fsync( int fildes);

//fildes : 파일 기술자


[3210w0@localhost ch02]$ man -s 3 fsync

fsync 함수는 메모리에 위치하고 있는 파일의 내용을 디스크보낸 메모리와 디스크의 내용을 동기화한다.
fsync 함수는 메모리의 내용이 디스크로 모두 기록되기 전에는 리턴하지 않는다.




728x90
반응형
Comments