블로그 이미지
하루, 글. 그림. 영상매체. 표현을 도와주는 기기들. 도전 중. 동화다아아
    동화다아아

    카테고리

    분류 전체보기 (176)
    잡담 (1)
    IT 기기-리뷰&뉴스 (7)
    리뷰 - 도서 (1)
    리뷰 - 영상 (0)
    리뷰 - 그림/음악 (1)
    내장형 하드웨어 (163)
    Total
    Today
    Yesterday

    - 시스템 레벨 입출력(저수준)

     → 시스템 레벨 입출력 또는 저수준 입출력은 운영체제가 디스크에 데이터를 읽거나 쓰기 위해서 접근하는 방법과 유사한 방법으로 데이터 입출력을 실행하며, 표준 입출력 함수들을 작성하기 위해서 사용되기도 한다.

     → 표준 입출력에서는 버퍼가 시스템에 의해서 마련되어 프로그래머에게 보이지 않지만, 저수준 입출력에서는 프로그램 내에서 버퍼를 명시해 주어야 한다. 디스크로의 데이터 입출력은 이 버퍼 단위로 이루어진다.

     → 저수준 입출력은 표준 입출력 함수에 비해 프로그램 코드가 짧으며 실행속도가 빠르다. 저수준 입출력에서 파일의 열기와 닫기에 사용되는 open() 함수와 close() 함수의 원형은 다음과 같다.

       int open(char *filename, int oflag, int pmode);

       int close(int fd);


    ⇒ oflag

     → open() 함수의 두 번째 인수인 oflag는 파일의 접근 목적이나 접근방법 등을 명시하는 것으로 <fcntl.h> 파일에 정의되어 있다.

    oflag

    의미

    O_APPEND

    0x0001

    쓰기용으로 파일을 열어, 파일의 끝을 현재위치로 설정한다.

    O_CREAT

    0x0002

    쓰기 용으로 파일을 생성한다. 파일이 이미 존재하면 효과가 없다.

    O_EXCEL

    0x0004

    O_CREAT와 함께 사용되어 파일이 이미 존재할 경우 오류값을 반환.

    O_RDONLY

    0x0100

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

    O_RDWR

    0x0200

    읽고 쓰기용으로 파일을 연다.

    O_TRUNC

    0x0400

    파일을 열고 내용을 삭제하여 파일의 길이를 0으로 만든다.

    O_WRONLY

    0x0800

    쓰기 전용으로 파일을 연다.

    O_BINARY

    0x4000

    이진 모드로 파일을 연다.

    O_TEXT

    0x8000

    텍스트 모드로 파일을 연다.

     → oflag의 값들은 상호 배타적이기 때문에 경우에 따라서는 여러개의 값을 주어야 한다.

     → 이때는 비트 OR 연산자(|)fmf 사용한다. 예로, 읽기 전용의 이진모드로 파일을 열 때는 다음과 같이 표현한다.

                    O_RDONLY | O_BINARY

     → 단, 읽기 전용과 쓰기 전용을 동시에 표시할 수는 없다.


    - 파일 핸들(리눅스에선 파일 디스크립터(descriptor))


     ⇒ 고수준 입출력시에는 파일을 열면 파일포인터(파일을 읽거나 쓸수 있게 해준다.)를 프로그램에서 연결받아 이후 파일에 대한 연산이 파일 포인터를 통해서 이루어 진다.

     ⇒ 반면, 저수준 입출력에서는 파일 포인터를 사용하지 않고 핸들(handle)이라고 부르는 파일기술자를 사용하여 파일에 대한 연산이 이루어진다. 이 값은 open() 함수의 반환값으로 양의 정수 갑이다. open() 함수는 오류가 발생할 경우 -1을 반환한다.

    장치

    파일핸들

    stdin

    0

    stdout

    1

    stderr

    2

    stdaux

    3

    stdprn

    4

     ⇒ 고수준일 때는 주소 FILE* fp, 저수준일 때는 번호


    - read() / write() 함수

     ⇒ 저수준 파일 입출력에서는 파일에 데이터를 읽고 쓰기 위해서 read() 함수와 write() 함수를 사용하며, 원형은 다음과 같다.

            int read (int fd, char *buffer, int size);

            int write (int fd, char *buffer, int size);

       → 첫 번째 인자(read라면 읽을 대상, write라면 쓰는 대상.)

       → 두 번째 인자(메모리 주소.)

       → 세 번째 인자(한번에 읽어올 최대 양)

     ⇒ read() 함수는 파일핸들(linux는 description) fd가 가리키는 파일에서 size 크기 만큼의 바이트를 buffer로 읽어 온다. 실행이 성공하면 읽은 바이트 수를 반환하고, EOF(End Of File)이면 0을, 오류가 발생하면 -1dmf 반환한다.

     ⇒ write() 함수에서 buffer는 파일에 기록할 데이터를 가지고 있다. 버퍼의 크기는 디스크의 입출력 속도를 향상시키는 데 매우 중요하며 운영체제에 따라 다르다. 보통 512부터 배수인 2048 또는 4096 바이트를 많이 사용한다.

     ⇒ 버퍼의 크기가 커지면 스택 오버플로우가 일어날 수 있으므로 전역변수로 선언해 주어야만 한다.


    - pmode

     ⇒ 마지막 인수인 pmode는 보통의 경우 생략되며, 새로운 파일은 만들기 위해서 O_CREAT을 사용했을 때 새로운 파일에 대한 접근 허가를 명시할 때 사용한다.

    pmode

    의미

    S_IWRITE

    쓰기 허용

    S_IREAD

    읽기 허용

    S_IREAD | S_IWRITE

    읽기와 쓰기 허용

     ⇒ pmode를 사용하기 위해선s #include를 사용하여 <sys/types.h> 파일과 <sys/stat.h> 파일을 포함시켜야 한다. oflag은 파일을 열 때 가지는 속성이므로 프로그램 내에서만 유요하다.

     ⇒ pmode는 새로운 파일 자체가 가지는 속성이다. 파일을 새로 만들었을 경우에는 시스템에 따라서 파일이 예상대로 작동하지 않는 경우가 있으므로 파일의 속성을 시스템에게 알리기 위해 한번 닫았다 다시 열어서 사용하는 것이 낫다.

     ⇒ open()함수로 연 파일은 close 함수로 닫아주면 된다. close() 함수의 실행시 파일 기술자(description)만을 인수로 넘겨주면 된다.

     ⇒ 새로운 파일을 작성할 때는 open() 함수 대신 creat() 함수를 사용할 수 있으며 그 원형은 다음과 같다.

                    int creat (char *filename, int pmode);

     ⇒ creat() 함수는 실패시 -1을 반환한다. pmode는 위의 open() 함수의 경우와 같다.


    // 입력 데이터 파일의 내용을 새로운 출력파일을 생성하여 복사하는 프로그램(linux)


    #include<stdio.h>
    #include<string.h>
    #include<fcntl.h>
    #include<sys/types.h>
    #include<sys/stat.h>

    #define BUFFERSIZE 512
    //#define file "d1009.in"
    int main()
    {
            
    int infd;
            
    int bytes;
            
    int i;
            
    int outfd;
            
    char buffer[BUFFERSIZE];

      //char는 문자열을 저장하려는게 아니라 정확하게 byte를 선언하려고 사용한다.
      //const char *file 
    = "d1009.in";

            
    if((infd = open(file, O_RDONLY)) <0)
            
    //if((infd = open("d1009.in", O_RDONLY)) <0)
            
    {
                    perror(
    "Can't open file d11-9.in");
            }
            
    if((outfd = open("d1009.out", O_CREAT|O_WRONLY, S_IWRITE))<0)

            // 인자 3개면 세세한 지정이 가능하나 두 개로도 동작한다.
            {
                    printf(
    "Can\t open file d11-9.out");
            }

            
    while((bytes = read (infd, buffer, BUFFERSIZE))>0)
            {
                    
    for(i=0;i<bytes; ++i)
                    {
                            putchar(buffer[i]);
                    }
                    write(outfd, buffer, bytes);
            }
            close(infd);
            close(outfd);
          
            
    return 0;
    }

    ⇒ 출력결과

            

     

    ⇒ #include<fcntl.h>

     → o_flag를 사용하기 위해서 <fcntl.h>파일을 #include 시킨다.

    ⇒ perror("Can't open file d11-9.in");

     → 데이터 파일이 없을 경우 다음과 같이 오류메세지를 출력한다.

      Can't open file d1009.in : No such file or directory


    ⇒ open("d1009.out", O_CREAT | O_WRONLY, SIWRITE)

     → 새로운 파일을 만들기 위해 O_CREAT를 명시하고, 쓰기전용의 이진 모드로 파일을 연다는 의미이다. O_CREAT가 명시되므로 pmode가 S_IWRITE로 명시되었다. open() 함수 대신 다음과 같이 creat() 함수를 사용하여 파일을 생성할 수 있다.

                    create ("d11-9.out", S_IWRITE);


    ⇒ #include<sys/types.h>

    ⇒ #include<sys/stat.h>

     → pmode를 사용하기 위해서 포함 시킨다.




    - HEXAVIEW로 파일 읽기

    #include<stdio.h>
    #include<fcntl.h>
    #include "hexaview.h"

    #define BUFFERSIZE 256 

    int main()
    {
            
    int bytes;
            
    int readfd;
            
    char buffer[BUFFERSIZE];
      
            readfd 
    =  open("test2.c",O_RDONLY); 
            
    // test2.c, test2, test2.exe 파일을 각각 읽어 본다.
            
    bytes = read(readfd, buffer, 256);
        
            hexaview(buffer, bytes);
            close(readfd);
            
    return 0;
    }

    ⇒ linux로 실행

     

     → test2라는 파일을 읽어들여 hexaview 형태로 뿌린다.

     → 처음은 test2.c 파일을 읽어들여 출력한 형태

     → 두 번째는 test2 파일(실행파일)을 읽어들여 출력한 형태


    ⇒ cl로 실행



     


      → test2.c를 cl로 컴파일하여 생성된 test2.exe 파일을 읽어들여 출력한 화면


     

    #include "MSDFunction.h"
    #include <stdlib.h>
    #include <fcntl.h>


    int main(int iParam, char *cpParam[])
    {
      
    int  iExeFile;
      unsigned 
    char  ucBuf[16*16]={0,}; //속도면에서는 초기화 하지 않는 것이 낫다.

      if(2 != iParam) //인자가 2개일때만 불러온다.
      {
        fprintf(stdout, 
    "파일 이름을 쓰세요\n");
        
    return 0;
      }

      iExeFile 
    = open(cpParam[1], O_RDONLY); //두번째, 세번째 인자파일
      if(0 > iExeFile)
      {
        fprintf(stdout, 
    "[%s]파일을 찾을 수 없습니다\n", cpParam[1]);
        
    return 0;
      }
      
      read(iExeFile, ucBuf, 
    16*16); //256이라고 적어도 되지만 

      MSDFunction(ucBuf, 16); // ucBUF

      close(iExeFile);
      
    return 0;
    }

    Posted by 동화다아아
    , |

    최근에 달린 댓글

    최근에 받은 트랙백

    글 보관함