카테고리 없음

메모리맵파일과 메모리사용한 파일 다루기 비교

에어버스 2018. 8. 29. 22:20

메모리맵핑 파일을 쓰기 위해서는 기존 파일을 열거나 새파일을 만들때 FILE_MAP_WRITE, FILE_MAP_READ, FILE_MAP_ALL_ACCESS, FILE_MAP_COPY 속성을 지정해야 한다.

Windows10 Pro 64bit, 64bit 로 컴파일
9GB TXT파일을 메모리에 저장해서 저장하는 시간과 메모리맵파일로 저장하는데 걸린 시간을 비교

아래 실행결과와 같이 메모리맵파일보다 메모리를 이용하는것이 빠르다.

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
96
97
98
99
100
101
102
103
104
105
106
107
void CMFCRESTTelegramDlg::파일처리()
{
    // TODO: 여기에 구현 코드 추가.
    CString strTime1, strTime2, strTime3;
    SYSTEMTIME curTime;
    GetLocalTime(&curTime);
    strTime1.Format("시작 : %02d:%02d:%02d", curTime.wHour, curTime.wMinute, curTime.wSecond);
    
    TCHAR* pFile;
    HANDLE hFileSrc, hFile, hMapFile;
    DWORD numOfByteWritten = 0;
    
    hFileSrc = CreateFile("DataLog.txt", GENERIC_READ, 0NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // 읽기파일
    if (hFileSrc == INVALID_HANDLE_VALUE)
    {
        AfxMessageBox("읽기 파일이 없습니다.");
        return;
    }
    hFile = CreateFile("test.txt", GENERIC_ALL | FILE_MAP_ALL_ACCESS, 0NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); // 쓰기파일
    if (hFile == INVALID_HANDLE_VALUE)
    {
 
        AfxMessageBox("쓰기 파일이 없습니다.");
        return;
    }
    LARGE_INTEGER FileSize;
    GetFileSizeEx(hFileSrc, &FileSize);
    TCHAR *pstrRead = new TCHAR[FileSize.QuadPart];
    __int64 size = 0;
    DWORD nNumberOfBytes;
    while(size < FileSize.QuadPart)
    {
        if (size + 4294967295 < FileSize.QuadPart)
            nNumberOfBytes = 4294967295;
        else
            nNumberOfBytes = FileSize.QuadPart - size;
        if (FALSE == ReadFile(hFileSrc, pstrRead+size, nNumberOfBytes, &numOfByteWritten, NULL))
        {
            AfxMessageBox("파일 읽기 실패!!!");
            return;
        }
        if(FALSE == WriteFile(hFile, pstrRead + size, nNumberOfBytes, &numOfByteWritten, NULL))
        {
            CloseHandle(hFileSrc);
            AfxMessageBox("파일 쓰기 실패!!!");
            return;
        }
        size += numOfByteWritten;
    }
    GetLocalTime(&curTime);
    strTime2.Format("종료 : %02d:%02d:%02d", curTime.wHour, curTime.wMinute, curTime.wSecond);
    CloseHandle(hFileSrc);
    CloseHandle(hFile);
    GetLocalTime(&curTime);
    delete[] pstrRead;
 
    // https://docs.microsoft.com/ko-kr/windows/desktop/FileIO/testing-for-the-end-of-a-file
 
    // 메모리맵핑파일을 만들기 위해 FILE_MAP_ALL_ACCESS 속성을 지정
    hFileSrc = CreateFile("DataLog.txt", GENERIC_READ | FILE_MAP_ALL_ACCESS, 0NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // 읽기파일    
    if (hFileSrc == INVALID_HANDLE_VALUE)
    {
        AfxMessageBox("읽기 파일이 없습니다.");
        return;
    }    
    hMapFile = CreateFileMapping(hFileSrc, NULL, PAGE_READWRITE, 00NULL);
    if (hMapFile == NULL)
    {
        DWORD err = GetLastError();
        LPVOID lpMsgBuf;
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR)&lpMsgBuf, 0NULL);
        MessageBox((LPCTSTR)lpMsgBuf, "오류 발생", MB_OK | MB_ICONINFORMATION);
        LocalFree(lpMsgBuf);
        CloseHandle(hFileSrc);
        return;
    }
    pFile = (TCHAR*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 00NULL);
    hFile = CreateFile("test.txt", GENERIC_ALL, 0NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); // 쓰기파일
    if (hFile == INVALID_HANDLE_VALUE)
    {
        AfxMessageBox("쓰기 파일이 없습니다.");
        return;
    }
    size = 0;
    GetFileSizeEx(hFileSrc, &FileSize);
    while (size < FileSize.QuadPart)
    {
        if (size + 4294967295 < FileSize.QuadPart)
            nNumberOfBytes = 4294967295;
        else
            nNumberOfBytes = FileSize.QuadPart - size;
        if (FALSE == WriteFile(hFile, pFile + size, nNumberOfBytes, &numOfByteWritten, NULL))
        {
            AfxMessageBox("파일 쓰기 실패!!!");
            break;
        }
        size += numOfByteWritten;
    }
    GetLocalTime(&curTime);
    strTime3.Format("종료 : %02d:%02d:%02d", curTime.wHour, curTime.wMinute, curTime.wSecond);    
    UnmapViewOfFile(pFile);
    CloseHandle(hMapFile);
    CloseHandle(hFile);
    AfxMessageBox(strTime1 + "\n" + strTime2 + "\n" + strTime3);
}
cs

<실행결과>