관리 메뉴

Kim's Programming

파일처리함수(2/2) 본문

Programming/System Programming

파일처리함수(2/2)

Programmer. 2015. 12. 25. 00:11

앞에서 이용했던 FILETIME 구조체 부터 알아보겠습니다 FILETIME 구조체의 구조는 다음과 같습니다.

1
2
3
4
typedef struct _FILETIME {
    DWORD dwLowDateTime;
    DWORD dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;
cs

위 구조체는 시간 정보를 나타내는 8바이트 자료형으로 UTC 기반의 시간을 표현하는 구조체입니다.


UTC란  Coordinated Universal Time의 약자로 세계시간의 기준을 의해 정의된 시간입니다. 간단히 설명하면 현재 시간과 1601년 1월 1일 사이의 시간을 100나노초 단위로 환산한 값이 UTC입니다.


아무튼 이번엔 GetFileTime 함수를 이용한 파일 시간을 UTC값을 얻은 다음 보기 좋게 바꾸는 소스를 짜보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#define _CRT_SECURE_NO_WARNINGS
#include<Windows.h>
#include<stdio.h>
#include<tchar.h>
 
int _tmain(int argc, TCHAR *argv[])
{
    TCHAR FileName[] = _T("data.txt");
 
    TCHAR FileCreateTimeInfo[100];
    TCHAR FileAccessTimeInfo[100];
    TCHAR FileWriteTimeInfo[100];
 
    FILETIME ftCreate, ftAccess, ftWrite;
 
    SYSTEMTIME stCreateUTC, stCreateLocal;
    SYSTEMTIME stAccessUTC, stAccessLocal;
    SYSTEMTIME stWriteUTC, stWriteLocal;
 
    HANDLE hFile;
 
    hFile = CreateFile(FileName, GENERIC_READ, 00, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        _tprintf(_T("Fail to open file\n"));
        return -1;
    }
    //
    if (!GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite))
    {
        _tprintf(_T("Unable to call GetFileTime Function\n"));
        return -1;
    }
    //
    FileTimeToSystemTime(&ftCreate, &stCreateUTC);
    SystemTimeToTzSpecificLocalTime(NULL, &stCreateUTC, &stCreateLocal);
 
    FileTimeToSystemTime(&ftAccess, &stAccessUTC);
    SystemTimeToTzSpecificLocalTime(NULL, &stAccessUTC, &stAccessLocal);
 
    FileTimeToSystemTime(&ftWrite, &stWriteUTC);
    SystemTimeToTzSpecificLocalTime(NULL, &stWriteUTC, &stWriteLocal);
    //
    _stprintf(FileCreateTimeInfo, _T("%02d/%02d/%02d   %02d:%02d"), stCreateLocal.wMonth, stCreateLocal.wDay, stCreateLocal.wYear, stCreateLocal.wHour, stCreateLocal.wMinute);
    _stprintf(FileAccessTimeInfo, _T("%02d/%02d/%02d   %02d:%02d"), stAccessLocal.wMonth, stAccessLocal.wDay, stAccessLocal.wYear, stAccessLocal.wHour, stAccessLocal.wMinute);
    _stprintf(FileWriteTimeInfo, _T("%02d/%02d/%02d   %02d:%02d"), stWriteLocal.wMonth, stWriteLocal.wDay, stWriteLocal.wYear, stWriteLocal.wHour, stWriteLocal.wMinute);
    //
    _tprintf(_T("File Created Time : %s\n"), FileCreateTimeInfo);
    _tprintf(_T("File Accessed Time : %s\n"), FileAccessTimeInfo);
    _tprintf(_T("File Written Time : %s\n"), FileWriteTimeInfo);
 
    CloseHandle(hFile);
}
cs


FileTimeToSystemTime 함수의 호출로 변경되는 것은 단순히 포맷입니다. 시간정보의 기준은 한국 기준이 아니라 UTC 기준이기 떄문에 다음의 SYSTEMTIME 구조체를 이용해서 변환 하게 됩니다.


1
2
3
4
5
6
7
8
9
10
typedef struct _SYSTEMTIME {
    WORD wYear;
    WORD wMonth;
    WORD wDayOfWeek;
    WORD wDay;
    WORD wHour;
    WORD wMinute;
    WORD wSecond;
    WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
cs


파일 사이즈 얻기

ANSI 표준 함수로는 파일사이즈를 다음과 같이 얻어오게 됩니다.
1
2
3
4
    FILE *fp = fopen("data.txt""rb");
 
    fseek(fp, 0, SEEK_END);
    DWORD FileSize = ftell(fp);
cs

하지만 윈도우에서는 GetFileSize함수를 이용해서 계산하여 사이즈를 반환해줍니다. GetFileSize함수에 대해서 알아보겠습니다.
1
2
3
4
DWORD GetFileSize(
    HANDLE hFile,
    LPDWORD lpFileSizeHigh
    );
cs
각 파라메터에 대해서 알아보겠습니다.

    • hFile : 파일 핸들을 지정, 이 핸들이 가리키는 파일의 크기 정보를 얻음
    • lpFileSizeHigh : 반환 타입이 DWORD이기 때문에 4기가 이상의 파일 크기를 반환 값으로 얻는 것이 불가하기 때문에 4G이상의 파일 크기를 얻을 때 사용합니다.
GetFileSize함수는 상위 하위 4바이트를 각각 따로 얻어야 하는데 이것이 불편하다면 GetFileSizeEx함수를 쓸 수 도 있습니다.

파일 사이즈를 얻는 예제 소스입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#define _CRT_SECURE_NO_WARNINGS
#include<Windows.h>
#include<stdio.h>
#include<tchar.h>
 
int _tmain(int argc, TCHAR *argv[])
{
    TCHAR FileName[] = _T("VS2013_RTM_ULT_KOR.iso");
 
    HANDLE hFile;
    
    DWORD high4byteFileSize = 0;
    DWORD low4ByteFileSize = 0;
 
    hFile = CreateFile(FileName, GENERIC_READ, 00, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        _tprintf(_T("Fail to open file\n"));
        return -1;
    }
    
    low4ByteFileSize = GetFileSize(hFile, &high4byteFileSize);
    _tprintf(_T("High 4 Byte File Size : %d\n"),high4byteFileSize);
    _tprintf(_T("Low 4 Byte File Size : %d\n"), low4ByteFileSize);
 
    LARGE_INTEGER fileSize;
    GetFileSizeEx(hFile, &fileSize);
    _tprintf(_T("Total file size : %lld byte \n"), fileSize.QuadPart);
 
    CloseHandle(hFile);
    return 0;
}
cs

결과는 다음과 같습니다.


작은 파일로 했을 때는 똑같이 잘 나오는데 큰파일로 했을 때 왜 GetFileSizeEx를 써야하는지 알 수 있습니다.


파일 특성 얻고 변경하기


속성에서 볼 수 있는 내용중 제일 밑에 있는 읽기 전용, 숨김(윈10 기준)등을 표시하는 함수는 GetFileAttribute 함수입니다. GetFileAttribute함수는 다음과 같습니다.

1
2
3
DWORD GetFileAttributesA(
    LPCSTR lpFileName
    );
cs

파라메터는 다음과 같습니다.

    • lpFileName : 특성 정보를 얻고자 하는 파일의 핸들을 지정


특성정보는 DWORD형으로 반환이 되게 됩니다.


또 특성정보를 설정하는 함수는 SetFileAttribute함수를 사용하게 됩니다. SetFileAttribute 함수는 다음과 같은 구조를 가지고 있습니다.

1
2
3
4
SetFileAttributesA(
    LPCSTR lpFileName,
    DWORD dwFileAttributes
    );
cs

각 파라메더는 다음과 같습니다.

    • lpFileName : 특성 정보를 변경하고싶은 파일의 핸들 지정
    • dwFileAttribute : 변경 할 특성 정보를 전달
다음 소스들을 이용한 프로그램입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#define _CRT_SECURE_NO_WARNINGS
#include<Windows.h>
#include<stdio.h>
#include<tchar.h>
 
void Show_Attribute(DWORD Attribute);
int _tmain(int argc, TCHAR *argv[])
{
    TCHAR FileName[] = _T("data.txt");
    DWORD Attribute;
    
    _tprintf(_T("Current File Attribute\n"));
    Attribute = GetFileAttributes(FileName);
    Show_Attribute(Attribute);//현재 설정 받아와서 현재 설정 확인
 
    Attribute |= (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN);
    SetFileAttributes(FileName, Attribute);//설정 변경
 
    _tprintf(_T("Changed File Attribute\n"));
    Attribute = GetFileAttributes(FileName);
    Show_Attribute(Attribute);//변경된 설정 확인
    return 0;
}
void Show_Attribute(DWORD Attribute)
{
    if (Attribute&FILE_ATTRIBUTE_NORMAL)
        _tprintf(_T("Normal\n"));
    else
    {
        if (Attribute&FILE_ATTRIBUTE_READONLY)
            _tprintf(_T("Read Only\n"));
        if (Attribute&FILE_ATTRIBUTE_HIDDEN);
        _tprintf(_T("Hidden\n"));
    }
}//겹치는 설정이 있으면 문자열 출력
cs


파일 특성을 변경하는 소스입니다.