01 . 기본적인파일 처리 함수들
파일을 열 때에는 다음 함수를 활용한다.
HANDLE CreateFile (
1. LPCSTR lpFileName // 개방할 파일 이름을 지정한다.
2. DWORD dwDesiredAccess // 읽기쓰기 모드를 지정한다 or 연산으로 결합 가능하다. GENERIC_READ 읽기모드지정 , GENIRICE_WRITE 쓰기 모드 지정
3.DWORD dwShareMode // 파일 공유 방식을 지정한다.
0 - 다른 프로세스에게 절대 공유 불가! 이미 개방된 파일은 중복 개방 불가
FILE_SHARED_READ 다른 프로세스에서 이 파일에 동시 읽기 접근 가능
FILE_SHARE_WRITE 다른 프로세스에서 이 파일에 동시 쓰기 접근 가능. 단 동시에 같은 영역에 데이터를 쓰는 문제를 피해야 함
4.LPSECURITY_ATTRIBUTES lpSecurityAttributes // 보안 속성을 지정한다. 핸들을 자식 프로세스에게 상속할 것인지 말 것인지를 결정하기 위한 용도로 사용할 수 있다. 디폴트 보안 속성을 지정하고자 하는 경우 NULL을 전달한다.
5.DWORD dwCreationDisposition // 파일이 생성되는 방법을 지정한다.
*CREATE_ALWAYS - 항상 새 파일을 생성한다.
*CREATE_NEW - 새 파일 생성, 같은 이름의 파일이 존재하면 생성 실패
*OPEN_ALWAYS - 기존 파일 개방, 없으면 새로 생성
*OPEN_EXISTING - 기존 파일 개방, 존재하지 않으면 함수 호출 실패
*TRUNCATE_EXISTING - 기존 파일의 내용 지우고 개방, 파일이 존재하지 않으면 호출 실패
6.DWORD dwFlagsAndAttributes - 파일의 특성 정보를 설정한다. 둘 이상의 특성 정보가 OR연산자를 통해서 지정될 수 있으며, 기본적으로 FILE_ATTRIBUE_NORMAL이라는 값을 사용한다. 이는 말그래도 특별한 특성을 지정하지 않은 보통 파일임을 의미한다. 이외에도 지정할 수 있는 값들이 상당히 많은데, 필요할 때마다 중간중간 설명하기로 하겠다.
7.HANDLE hTemplateFile - 기존에 존재하는 파일과 동일한 특성을 가지는 새 파일을 만들 때 사용되는 전달인자이다.
끝으로 함수호출이 성공하면 파일의 핸들이 반환된다.
);
파일 종료 CloseHandle 호출. CreateFile 함수는 핸들을 반환.
-파일 읽기 쓰기와 포인터
파일에 데이터를 읽을 때에는 다음 함수를 사용하다.
BOOL ReadFile (
HANDLE hFile // 데이터를 읽을 파일의 핸들을 지정한다.
LPVOID lpBuffer // 읽어 들인 데이터를 저장할 버퍼(배열,메모리)의 주소(포인터)를 지정한다.
DWORD nNumberOfBytesToRead // 파일로부터 읽고자 하는 데이터의 크기를 바이트 단위로 지정한다.
LPDWROD lpNumberOfBytesRead // 실제 읽어 들인 데이터 크기를 얻기 위한 변수의 주소를 지정한다.
LPOVERLAPPED lpOverlapped // 추후 설명
);
반대로 파일에 데이터를 저장할 때에는 다음 함수를 사용한다.
BOOL WriteFile (
HANDLE hFile // 데이터를 저장할 파일의 핸들을 지정한다.
LPVOID lpBuffer // 데이터를 저장하고있는 버퍼(배열,메모리)의 주소 (포인터)를 지정한다.
DWORD nNumberOfBytesToWrite // 파일에 저장하고자 하는 데이터 크기를 바이트 단위로 지정한다.
LPDWROD lpNumberOfBytesWritten // 파일에 실제 저장된 데이터 크기를 얻기 위해 변수의 주소를 지정한다.
LPOVERLAPPED lpOverlapped // 추후 설명
);
-파일의 시간 정보 얻어오기
BOOL GetFileTime (
1. HANDLE hFile // 시간 관련 정보를 얻을 대상 파일의 핸들을 지정한다.
2. LPFILETIME lpCreationTime // 파일이 생성된 시간을 얻기 위해 FILETIME 구조체 변수의 주소값을 전달한다. NULL을 전달하는 것도 가능하다.
3. LPFILETIME lpLastAccessTime // 파일의 마지막 접근 시간을 얻기 위해 FILETIME 구조체 변수의 주소값을 전달한다. NULL을 전달하는 것도 가능하다.
4. LPFILETIME lpLastWriteTime // 파일의 마지막 데이터갱신(덮어 쓰기 포함) 시간을 얻기 위해 FILETIME 구조체 변수의 주소값을 전달한다. NULL을 전달하는 것도 가능하다.
);
typedef struct _FILETIME {
DWORD dwLowDateTime
DWORD dwHighDateTime
} FILETIME, * PFILETIME;
FILETIME 구조체는 시간 정보를 나타나내느 8바이트 자료형이다(DWORD * 2)이다. 그리고 이 구조체는 UTC 기반으로 시간을 표현한다.
"GetFileTime 함수는 UTC 기반으로 시간 정보를 돌려 준다"
UTC란 "Coordinated Universal Time"의 간략한 표현으로써 세계 시간의 기준을 만들기 위해 정의된 시간이다.
FileTimeToSystemTime - 첫번째 인자로 전달된 파일 시간의 정보를 SYSTEMTIME 구조체의 포맷으로 변경해서 적절히 채워주는 역할을 한다. 두번째 전달인자의 stCreateUTC는 SYSTEMTIME 구조체의 변수이다.
이함수의 호출로 변경되는 것은 단지 포맷이다.
SystemTimeToTzSpecificLocalTime 함수는 UTC를 지역별, 국가별 시간대로 변경하는 기능을 지닌다.
SystemTimeTOTzSpecificLocalTime( NULL, &stCreateUTC, &stCreateLocal);
첫 번째 전달인자는 변경하고자 하는 시간대에 대한 정보이다. NULL이 전달되면 현재 시스템의 시간대 정보가 기준이 된다. 따라서 우리가 원하는 한국 시간대 정보를 기준으로 변경이 이뤄진다. 두 번째 전달인자는 변경할 대상이 되는 UTC 기반 시간 정보이고, 세 번째 전달인자는 변환된 시간 정보가 채워질 변수의 주소값이다.
-파일 사이즈 얻어오기
ANSI 표준 함수에서는 다음과 같은 형태로 파일사이즈를 얻어왔다.
FILE * fp = fopen("test.dat", "rb");
fseek(fp,0,SEEK_END);
DWORD sizeOfFile = ftell(fp)
fseek 함수로 파일 포인터를 끝으로 이동시킨 다음, ftell 함수를 호출해서 현재 위치 정보를 얻어온다. 파일 포인터를 끝으로 이동시켰기 때문에 현재 위치 정보는 파일의 크기가 된다. 다소 번거롭다. Windows 시스템 함수는 파일 크기를 직접 계산해서 반환해주는 함수를 제공한다.
DWROD GetFileSize (
HANDLE hFile //파일 핸들을 지정한다. 이 핸들이 가리키는 파일의 크기 정보를 얻게된다.
LPWORD lpFileSizeHigh // 반환 타입을 보면 4바이트 DWORD로 선언되어 있다. 따라서 4G바이트 이상의 파일 크기를 반환값으로 얻는 것은 불가능하다. 4G바이트 이상 되는 파일의 크기를 얻을 때 사용 되는 것이 두 번째 전달인자 이다. 이 전달인자를 통해 크기가 4G 바이트를 넘는 파일의 상위 4바이트 정보를 얻을 수 있다.
GetFileSize 함수는 4G바이트 이상의 파일에 대해서 상위 4바이트와 하위 4바이트를 각각 다른 경로를 통해서 얻어야 한다. 이것이 불편하다면 다음 함수의 사용을 고려해 볼 수 있다.
BOOL GetFileSizeEx (
HANDLE hFile // 크기를 얻고자 하는 파일의 핸들을 지정한다.
PLARGE_INTEGER lpFileSize // 파일 크기를 지정하기 위한 변수의 포인터를 인자로 전달한다. PLARGE_INTEGER는 LARGE_INTEGER의 포인터 타입이고, LARGE_INTEGER는 다음과 같이 선언되어 있다. 중요한 사실은 4바이트가 아니라 8바이트 자료형이라는 것이다.
-파일의 특성 정보 얻어오기
이러한 특성 정보는 프로그램 코드상에서 변경 및 확인이 가능하다.
DWROD GetFileAttributes (
LPCTSTR lpFileName - 특성 정보를 얻고자 하는 파일의 핸들을 지정한다 파일의 특성 정보는 반환값을 통해서 얻게 된다.
);
위 함수의 호출을 통해서 DWORD형 반환값을 얻을 수 있다. 이 안에 파일 특성에 대한 정보들이 모두 들어 있다. 하나의 값에 여러 정보가 담겨있다 보니, 비트 단위로 의미가 부여되어 있다.
오른쪽 첫비트 - 읽기 전용 특성 1일경우 읽기 전용
오른쪽 두번째 - 숨김 특성
이외에도 12가지 정도가 더있다 MSDN 참고
BOOL SetFileAttributes (
LPCTSTR lpFileName - 특성 정보를 변경하고픈 파일의 핸들을 지정한다
DWORD dwFileAttributes - 변경할 특성 정보를 전달한다.
);
GetFileAttributes 함수와 SetFileAttributes 함수는 일반적인 파일 처리 함수와 달리 파일 핸들을 필요로 하지 안흔다 대신 위치경로를 포함하는 파일의 이름을 필요로 한다.
BOOL GetFileInformationByHandle (
HANDLE hFile // 정보를 얻고자 하는 파일의 핸들을 지정한다.
LPBY_HANDLE_FILE_INFORMATION lpFileInformation // 구조체 BY_HANDLE_FILE_INFORMATION의 포인터 타입이다. 여기로 전달되는 주소의 변수에 파일 정보가 채워진다.
);
이함수를 통해서 얻는 정보는 파일의 특성 정보뿐만 아니라 시간정보와 파일의 크기 정보를 비롯해서 추가적인 파일 시스템 정보들도 얻을 수 있다. 때문에 이 함수의 호출은 앞서 설명한 GetFileTime함수와 GetFileSize함수의 호출을 대신할 수 있다. 구조체 BY_HANDLE_FILE_INFORMATION의 선언을 보자
DWORD GetFullPathName (
LPCTSTR lpFileName- 완전경로를 확인하고자 하는 파일 이름을 전달한다.
DWORD nBufferLength - 완전경로를 저장할 버퍼에 저장 가능한 문자열 길이를 지정한다. 주의하라! 버퍼의 바이트 단위 크기가 아니라, 저장가능한 문자열의 길이다.
LPTSTR lpBuffer - 완전경로를 저장할 버퍼의 주소값을 지정한다.
LPTSTR* lpFilePar - 완전경로가 문자열로 버퍼에 저장된 이후, 버퍼의 특정 위치를 가리키는 포인터 값이 저장되는데, 예제를 통해서 어디를 가리키는지 직접 확인하도록 하자
);
-파일 포인터의 이동 - 32비트 기반
DWROD SetFilePointer (
HANDLE hFile - 파일 포인터 위치를 이동시킬 대상 파일의 핸들을 지정한다.
LONG lDistanceToMove - 이동시킬 거리를 지정한다. 만약에 64비트 기반으로 구현한다면, 하위 4바이트 정보를 표현하게 된다.
lDistanceToMoveHigh - 64 비트 기반의 대용량 파일 에서만 의미를 지닌다. 상위 4바이트 정보를 표현하게 된다. 32 비트 기반에서는 null을 전달한다.
DWORD dwMoveMethod - 파일 포인터 이동 시 기준이 되는 위치를 지정한다. 파일의 가장 앞부분을 기준으로 설정하고자 할 때에는 FILE_BEGIN을 인자로 전달한다. fseek 함수의 SEEK_SET에 해당한다. 파일 포인터의 현재 위치를 기준으로 설정하고자 할 때에는 FILE_CURRENT를 인자로 전달한다. fseek 함수의 SEEK_CUR에 해당한다. 파일의 가장 마지막 부분을 기준으로 할 때에는 FILE_END를 인자로 전달한다. fseek 함수의 SEEK_END에 해당한다.
);
02 . 디렉터리 관렴 함수 및 그밖의 함수들
BOOL CreateDirectory (
LPCTSTR lpPathName // 생성하고자 하는 디렉터리 이름을 지정한다.
lpSecurityAttributes // 보안 속성을 지정할 때 사용된다. 이 책에서는 보안에 관련해서,특히 ACL에 관련해서 언급하지 않으므로, 기본적으로 NULL을 전달해서 디폴트 보안 속성을 지정하기로 하겠다.
);
BOOL RemoveDirectoty (
LPCTSTR lpPathName // 소멸하고자 하는 디렉터리 이름을 지정한다.
);
-현재 디렉터리, 시스템 디렉터리 그리고 Windows 디렉터리
현재 디렉터리 - 프로그램이 로드된 디렉터리
프로그램이 실행된 직후,현재 디렉터리는 실행파일이 존재하는 디렉터리로 설정되기 때문에 틀린것은 아니지만 그러나 현재 디렉터리 위치는 프로그램이 실행된 이후 얼마든지 변경 가능하기 때문에 다음과 같이 표현하는 것이 옳다.
"초기에는 프로그램이 로드된 디렉터리로 설정되며, 이후 변경 가능하다."
현재 디렉터리는 완전경로를지정하지않았을때 파일을 생성하고 실행파일을 찾는 표준 검색 경로 중 하나로서 사용된다.
DWORD GetCurrentDirectory(
DWORD nBufferLength - 두 번째 인자로 전달된 버퍼의 길이를 지정한다.
LPTSTR lpBuffer - 현재 디렉터리 정보를 저장할 버퍼의 주소값을 지정한다.
);
BOOL SetCurrentDirectory (
LPCTSTR lpPathName // 변경하고자 하는 현재 디렉터리 정보를 지정한다.
);
-시스템 디렉터리 & Windows 디렉터리
시스템 디렉터리는 각종 라이브러리 및 드라이버 파일처럼 Windwos 시스템에 중요한 파일들이 존재하는 위치고, Windows 디렉터리는 초기화 및 실행파일들이 존재하는 위치이다. 이는 변경하면 안 되는 디렉터리 들이다.
UINT GetSystemDirectoty (
LPTSTR lpBuffer // 시스템 디렉터리 정보를 저장할 버퍼의 주소값을 지정한다.
UINT uSize // 첫 번째 인자로 전달된 버퍼의 길이를 지정한다.
);
UINT GetWindowsDirectory (
LPTSTR lpBuffer // Windows 디렉터리 정보를 저장할 버퍼의 주소값을 지정한다.
UINT uSiz // 첫 번째 인자로 전달된 버퍼의 길이를 지정한다.
);
-디렉터리에서 파일 찾기
다음은 문자열로 지정한 경로에 특정 파일이 존재하는지 확인하는 용도로 사용할 수 있는 함수이다. 파일 이름을 인자로 해서 해당 파일이 저장되어 있는 완전 경로 정보를 얻고자 할 때에 사용할수도 있다.
DWORD SearcgPath (
LPCTSTR lpPath // 대상 경로를 지정한다.이 인자를 통해서 지정된 경로에서 파일을 찾게 된다. 그런데 인자로 NULL이 전달되면, 다음과 같은 순서로 파일을 찾게 된다. 이 경로를 가리켜 표준 검색 경로라 한다.
1. 실행 중인 프로그램이 로드된 디렉터리(실행파일이 존재하는 디렉터리)
2. 현재 디렉터리
3. 시스템 디렉터리
4. Windows 디렉터리
5. 마지막으로 환경변수 PATH에 등록된 디렉터리들
LPCSTR lpFileName // 찾고자 하는 파일 이름
LPCSTR lpExtension // 확장자를 지정하는 인자로서 첫 번째 문자는 반드시 . 으로 시작해야한다. lpFileName이 확장자를 포함하고 있거나 확장자를 지정해 줄 필요가 없을 때에는 NULL을 지정한다.
DWORD nBufferLength // 완전 경로명을 저장할 버퍼의 길이를 지정한다.
LPCSTR lpBuffer // 완전경로명을 저장할 버퍼의 주소를 지정한다.
LPCSTR lpFilePart // 함수 호출 결과로 얻게 되는 완전경로명의 마지막ㅇ에는 파일이름도 추가된다. 이전달인자를 통해서 파일 이름이 저장된 위치 정보를 얻게된다.
);
이것만은 알고 갑시다.
가장 기본이 되는 데이터 입/출력 및 파일 생성 함수의 사용방법을 기억하자.
64비트 시스템에서 4G바이트 이상 대용량 파일 처리와 관련해서 설명했던 모든 부분을 이해하자.
3.표준 검색경로
표준 검색경로를 기억하자. Windows 시스템은 파일을 찾을 때 이 경로를 기준으로 검색을 한다.
파일,디렉터리 관련 함수들 모두를 기억할 순 없지만, 어떠한 기능이 제공되는지 정도는 알고있자.