본문 바로가기
C/[서적] 뇌를 자극하는 윈도우즈 시프

Chapter 18. 파일 I/O와 디렉터리 컨트롤

by GameStudy 2022. 2. 14.

Note) ANSI에서는 파일 I/O에 대해 규격을 정해놓음.

  그럼 그렇게 정의된 ANSI 표준 파일 I/O 함수를 쓰면

  Windows, Linux, Unix, ...와 같은 플랫폼과 독립적으로

  똑같은 과정으로 똑같은 결과물을 얻을 수 있음.

  그럼 이걸 어떻게 구성했는지에 대해 알아보자.

 

Note) 하드웨어에 Window를 설치할수도, Linux나 Unix를 설치할 수도 있음.

  그리고 그 OS위에 APP이 실행됨. 파일을 하나 생성하고 저장했다고 해보자.

  그럼 파일이 저장되는 방식은 File System에 의존적임.

  파일을 어떻게 정의하고 어떻게 구성할 것이냐에 대한 것이 File System.

  이는 OS의 중요한 일부.

  어찌되었든, ANSI 이전에는 각 OS의 File System 함수들이 완성되어 있었음.

  즉 우리는 ANSI 표준 함수를 통해서도, File System 함수를 통해서도 만들 수 있음.

  그럼 그 둘의 차이점이 뭐지? ANSI 표준 함수 fopen()은 만약 Windows 위에서

  동작하는 프로그램이라면 Windows File System 함수를 호출함. 다른 OS도 마찬가지.

  그래서 ANSI 표준 함수는 세 운영체제가 공통으로 제공하는 File System 함수들만 모아서

  제공할 수 밖에 없음. 왜? 다른 OS에선 제공안할 수도 있기 때문.

  즉 Windows에서 좀 더 세밀한 File I/O 작업을 해야한다면, Windows File System을

  활용 해야만 가능함.

 

 

18.1-1 파일 관련 기본 함수들

  Note) 파일 생성

    - CreatFile()

 

  Note) 입력 및 출력

    - ReadFile(), WriteFile()

 

  Note) 파일 종료

    - CloseHandle()

 

 

18.1-2 파일 정보 얻어오기

  Note) GetFileTime()

    - 만든 날짜, 수정한 날짜, 엑세스한 날짜

    - 핸들을 통해 정보 확인.

 

  Note) GetFileAttributes()

    - 읽기 전용, 숨김, 보관

    - 파일 이름을 통해 정보 확인

 

  Note) GetFileInformationByHandle()

    - 위 두 함수를 통해 얻을 수 있는 정보 모두 얻을 수 있음.

    - 핸들을 통해 정보 확인.

 

 

18.1-3 파일 포인터의 이동

  Note) 32비트 기반

    - SetFilePointer(hFile, sizeof(TCHAR)*4, NULL, FILE_BEGIN);

      ANSI 표준 함수로는 fseek()

// SetFilePointer() 함수는 기본적으로 64비트 기반 함수임.

SetFilePointer(
    hFile,           // 파일의 핸들정보
    sizeof(TCHAR)*4, // 2^64-3 중, 0 ~ 2^32 - 1까지
    NULL,            // 2^64-3 중, 2^32 ~ 2^64-3까지(32bit 플랫폼이라 이부분은 NULL)
    FILE_BEGIN       // 어디를 기준으로 파일 포인터를 옮길건가
);

    - 파일 최대 크기: 4GB - 2

      2^32 == 0~4GB

      0~2^32 - 1 == 0~4GB - 1

      근데 4GB - 1을 특별한 의미(오류)로 빼둠.

      그래서 파일의 최대 크기는 4GB - 2로 제한함.

    - 4GB - 1 == INVALID_SET_FILE_POINTER(0xFFFFFFFF)

 

  Note) 64비트 기반

    - SetFilePointer(hFile, IDistanceLow, &IDistanceHigh, FILE_BEGIN);

      다만, 64비트 기반 플랫폼이라도, SetFilePointer()의 반환값은 하위 4바이트임.

      그럼 나머지 상위 4바이트는 어디? &IDistanceHigh를 통해서 받을 수 있음.

      웃긴건, 반환된 값이 0xFFFFFFFF이면 32비트때와 마찬가지로 오류를 의미.

      근데 64비트 기반에선 딱 4GB-1의 파일일수도 있기때문에 아래와 같이 검사해야함.

    - 4GB - 1의 검사

      dwPtrLow = SetFilePointer(...)

      if ( (INVALIDE_SET_FILE_POINTER == dwPtrLow) && (NOERROR != GetLastError()))

 

 

 

 

 

 

댓글