기본적인 파일 처리 함수들
Windows 기반 파일 입출력 함수
파일 열기 : CreateFile
HANDLE CreateFile(
LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
);
1.lpFileName : 개방(Open)할 파일 이름을 지정한다.
2.dwDesiredAccess : 읽기/쓰기 모드를 지정한다. or(|)연산으로 결합 가능하다.
- GENERIC_READ 읽기모드 지정
- GENERIC_WRITE 쓰기모드 지정
3.dwShareMode : 파일 공유방식을 지정한다.
- 0 : 다른 프로세스에 절대 공유 불가, 이미 개방된 파일은 중복 개방 불가
- FILE_SHARE_READ : 다른 프로세스에서 이 파일에 동시 읽기 접근 가능
- FILE_SHARE_WRITE : 다른 프로세스에서 이 파일에 동시 쓰기 접근 가능, 단 동시에 같은 영역에 데이터를 쓰는 문제를 피해야 함.
4.lpSecurityAttributes : 보안 속성을 지정한다. 핸들을 자식 프로세스에게 상속할 것인지 말 것인지를 결정하기 위한 용도로 사용할 수 있다. 디폴트 보안 속성을 지정하고자 하는 경우 NULL 전달
5.dwCreationDisposition : 파일이 생성되는 방법을 지정한다.
- CREATE_ALWAYS : 항상 새 파일을 생성한다.
- CREATE_NEW : 새 파일 생성, 같은 이름의 파일이 존재하면 생성 실패!
- OPEN_ALWAYS : 기존 파일 개방, 없으면 새로 생성
- OPEN_EXISTING : 기존 파일 개방, 존재하지 않으면 함수 호출
6.dwFlagsAndAttributes : 파일의 특성정보를 설정한다. 둘이상의 특성 정보는 OR(|) 연산자를 통해서 지정할 수 있으며, 기본적으로 FILE_ATTRIBUTE_NORMAL 값 사용
7.hTemplateFile : 기존에 존재하는 파일과 동일한 특성을 가지는 새파일을 만들 때 사용되는 전달인자이다.
위 함수 호출시, 파일의 핸들이 반환된다.
CreateFile로 파일을 열고 파일을 종료할 때에는 여느 커널 오브젝트의 핸들과 마찬가지로 CloseHandle 함수를 호출하면 된다.
CreateFile 함수는 핸들을 반환한다. 해당 핸들의 커널오브젝트에는 파일에 대한 정보로 가득 차있을 것이다.
파일 읽기 & 쓰기 함수
파일 읽기 함수
BOOL ReadFile(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);
1.hFile : 데이터를 읽을 파이르이 핸들을 지정한다.
2.lpBuffer : 읽어들인 데이터를 저장할 버퍼(배열, 메모리)의 주소(포인터)를 지정한다.
3.nNumberOfBytesToRead : 파일로 부터 읽고자 하는 데이터의 크기를 바이트 단위로 지정한다.
4.lpNumberOfBytesRead : 실제 읽어들인 데이터 크기를 얻기위한 변수의 주소를 지정한다.
파일 쓰기 함수
BOOL WriteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
1.hFile : 데이터를 저장할 파일의 핸들을 지정한다.
2.lpBuffer : 데이터를 저장하고 있는 버퍼(배열, 메모리)의 주소(포인터)를 지정한다.
3.nNumberOfBytesToWrite : 파일에 저장하고자 하는 데이터 크기를 바이트 단위로 지정한다.
4.lpNumberOfBytesWritten : 파일에 실제 저장된 데이터 크기를 얻기위해 변수의 주소를 지정한다.
파일의 시간 정보 얻어오기
Windows에서는 파일의 만든날짜, 수정한 날짜(마지막으로 수정한 날짜), 엑세스한 날짜(마지막으로 엑세스한 날짜)등의 정보를 확인할 수 있다.
프로그램상에서 위와같은 정보를 얻거나 변경하기 위한 함수
BOOL GetFileTime(
HANDLE hFile,
LPFILETIME lpCreationTime,
LPFILETIME lpLastAccessTime,
LPFILETIME lpLastWriteTime
);
1. hFile : 시간 관련 정보를 얻을 대상 파일의 핸들을 지정한다.
2. lpCreationTime : 파일이 생성된 시간을 얻기 위해 FILETIME 구조체 변수의 주소 값을 전달한다. NULL을 전달하는 것도 가능하다.
3. lpLastAccessTime : 파일의 마지막 접근 시간을 얻기위해 FILETIME 구조체 변수의 주소값을 전달한다. NULL을 전달하는 것도 가능하다.
4.lpLastWriteTime : 파일의 마지막 데이터 갱신(덮어쓰기 포함) 시간을 얻기위해 FILETIME 구조체 변수의 주소값을 전달한다. NULL을 전달하는 것도 가능하다.
FILTIME 구조체
typedef struct _FILETIME{
DWORD dwLowDataTime,
DWORD dwHighDataTime,
}FILETIME, *PFILETIME
FILETIME 구조체는 시간 정보를 나타내는 8바이트(DWORD *2)자료형이다. 이 구조체는 UTC 기반으로 시간을 표현한다.
UTC:Coordinated Universal Time의 간략한 표현으로써 세계시간의 기준을 만들기 위해 정의된 시간이다.
FileTimeToSystemTime 함수의 호출로 변경되는것은 단지 포맷이다.
SYSTEMTIME 구조체 선언
typedef struct _SYSTEMTIME{
WORD wYear,
WORD wMonth,
WORD wDayOfWeek,
WORD wDay,
WORD wHour,
WORD wMinute,
WORD wSecond,
WORD wMilliseconds
}SYSTEMTIME, *PSYSTEMTIME;
FileTimeToSystemTime 함수를 통해 FILETIME 표맷을 SYSTEMTIME포맷으로 변경한다.
SystemTimeToTzSpecificLocalTime 함수는 UTC를 지역별, 국가별 시간대(Time zone)로 변경하는 기능을 지닌다.
SystemTimeToTzSpecificLocalTime(NULL, &stCreateUTC, &StCreateLocal)
첫번째 인자는 변경하고자 하는 시간대에 대한 정보이다. NULL이 전달되면 현재 시스템의 시간대 정보가 기준이 된다. 두번째 전달인자는 변경할 대상이 되는 UTC 기반정보이고, 세번째 전달인자는 변환된 시간정보가 채워질 변수의 주소값이다.
GetFileTime 함수를 이용하여 파일의 시간정보를 얻어올 수 있고, SetFileTime 함수를 이용하여 파일의 시간정보를 변경할 수도 있다.
파일 사이즈 얻어오기
일반적으로 파일 사이즈를 얻어오는 코드
FILE * fp = fopen("abc.dat", "rb");
fseek(fp, 0, SEEK_END);
DWORD sizeofFile = ftell(fp);
위 방법은 fseek 함수로 파일 포인터를 끝으로 이동시킨 다음, ftell 함수를 호출해서 현재 위치정보를 얻어온다. 파일 포인터가 파일의 끝으로 설정되어 있기 때문에 현재 위치 정보는 파일의 크기가 된다.
Windows 시스템함수는 파일 크기를 직접 계산해서 반환하는 함수를 제공한다.
DWORD GetFileSize(
HANDLE hFile,
LPDWORD lpFileSizeHigh
);
1.hFile : 파일 핸들을 지정한다. 이 핸들이 가리키는 파이르이 크기정보를 얻게된다.
2.lpFileSizeHigh : 반환 타입을 보면 4바이트 DWORD로 선언되어있다. 따라서 4G바이트 이상의 파일 크기를 반환값으로 얻는것은 불가능하다. 4G바이트 이상되는 파일의 크기를 얻을 때 사용된다. 이 전달인자를 통해 4G바이트를 넘는 파일의 상위 4바이트 정보를 얻을 수 있다.
GetFileSize 함수는 4G바이트 이상의 파일에 대해서 상위 4바이트와 하위 4바이트를 각각 다른 경로를 통해서 얻어야 한다. 그러나 GetFileSizeEx함수를 사용하면 한번에 얻을 수 있다.
BOOL GetFileSizeEx(
HANDLE hFile,
PLARGE_INTEGER lpFileSize
);
1.hFile : 크기를 얻고자 하는 파일의 핸들을 지정한다.
2.lpFileSize : 파일 크기를 저장하기 위한 변수의 포인터(주소 값)을 인자로 전달한다. PLARGE_INTEGER는 LARGE_INTEGER의 포인터 타입이고, LARGE_INTEGER는 다음과 같이 선언되어 있다. 중요한 사실은 4바이트가 아니라 8바이트 자료형이라는 것이다.
typedef union _LARGE_INTEGER
{
struct {
DWORD LowPart;
LONG HighPart;
};
LONGLONG QuadPart;
}LARGE_INTEGER, *PLARGE_INTEGER;
'Programming > Windows System Programming' 카테고리의 다른 글
파일 I/O 와 디렉터리 컨트롤(3) (0) | 2020.08.19 |
---|---|
파일 I/O 와 디렉터리 컨트롤(2) (0) | 2020.08.19 |
SEH(Structured Exception Handling) (0) | 2020.08.10 |
가상 메모리(Virtual Memory) (0) | 2020.08.08 |
캐쉬(cache)와 캐쉬 알고리즘 (0) | 2020.08.07 |