Thinking Different





간단히 파일 매핑 ( CreateFileMapping, OpenFileMapping 등) 을 사용하여 파일 복사를 구현한 예제

간단히 대용량 파일을 빠르게 읽고 쓰는 프로그램을 사용하기 위해서 간단히 예제 구현한 소스


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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL, "korean");
 
    // main() argument 에러 처리
    if (argc != 3)
    {
        wcout << argv[0] << _T(" [Src File] [Dest File]") << endl;
        return -1;
    }
 
    //----------------------------------------
    // Global Variable 할당
    //----------------------------------------
    HANDLE hFileRead = INVALID_HANDLE_VALUE;
    HANDLE hFileWrite = INVALID_HANDLE_VALUE;
    HANDLE hFileMap = INVALID_HANDLE_VALUE;
 
    LARGE_INTEGER filesize;
    ULONGLONG bytes_left = 0;
    DWORD bytes_written = 0;
 
    SYSTEM_INFO si;
    GetSystemInfo(&si);
 
    DWORD iWriteByte = 0;
    LARGE_INTEGER now = { 0 };
 
    BYTE *pMapByte = NULL;
 
    try
    {
        // 원본 파일 열기
        hFileRead = CreateFile(argv[0], GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFileRead == INVALID_HANDLE_VALUE)
            throw true;
 
        // 대상 파일 열기
        hFileWrite = CreateFile(argv[1], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
        if (hFileWrite == INVALID_HANDLE_VALUE)
            throw true;
 
        // 파일 매핑
        hFileMap = CreateFileMapping(hFileRead, NULL, PAGE_READWRITE, 0, 0, NULL);
        if (hFileMap == INVALID_HANDLE_VALUE)
            throw true;
 
        // 원본 파일 사이즈 구하기
        if (!GetFileSizeEx(hFileRead, &filesize))
            throw true;
 
        // 남은 Byte
        bytes_left = filesize.QuadPart;
 
        // 파일 복사 처리
        // 대용량 파일의 분할 접근을 위해 임의 접근 및 복사를 나누어 진행
        // MapViewOfFile 의 임의 접근을 위해서는 시스템의 Allocation Granularity 값의 배수가 적용되어야 됨
        while (bytes_left > 0)
        {
            iWriteByte = bytes_left > si.dwAllocationGranularity ? si.dwAllocationGranularity : bytes_left;
        
            // 메모리 맵에서 iWriteByte 만큼 읽음
            pMapByte = (BYTE*)MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, now.HighPart, now.LowPart, iWriteByte);
 
            // iWriteByte 만큼 쓰기
            WriteFile(hFileWrite, pMapByte, iWriteByte, &bytes_written, NULL);
            
            // 메모리 맵 뷰 해제
            UnmapViewOfFile(pMapByte);
        
            // 파일 포인터 저장
            now.QuadPart += iWriteByte;
            bytes_left -= iWriteByte;
        } 
    }
    catch (...)
    {
        wcout << _T("Error Abort!") << endl;
    }
    
 
    //----------------------------------------
    // 핸들 닫기
    //----------------------------------------
    if (hFileMap != INVALID_HANDLE_VALUE)
        CloseHandle(hFileMap);
 
    if (hFileWrite != INVALID_HANDLE_VALUE)
        CloseHandle(hFileWrite);
 
    if (hFileRead != INVALID_HANDLE_VALUE)
        CloseHandle(hFileRead);
 
    return 0;
}