카테고리 없음
메모리맵파일과 메모리사용한 파일 다루기 비교
에어버스
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, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // 읽기파일
if (hFileSrc == INVALID_HANDLE_VALUE)
{
AfxMessageBox("읽기 파일이 없습니다.");
return;
}
hFile = CreateFile("test.txt", GENERIC_ALL | FILE_MAP_ALL_ACCESS, 0, NULL, 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, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // 읽기파일
if (hFileSrc == INVALID_HANDLE_VALUE)
{
AfxMessageBox("읽기 파일이 없습니다.");
return;
}
hMapFile = CreateFileMapping(hFileSrc, NULL, PAGE_READWRITE, 0, 0, NULL);
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, 0, NULL);
MessageBox((LPCTSTR)lpMsgBuf, "오류 발생", MB_OK | MB_ICONINFORMATION);
LocalFree(lpMsgBuf);
CloseHandle(hFileSrc);
return;
}
pFile = (TCHAR*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, NULL);
hFile = CreateFile("test.txt", GENERIC_ALL, 0, NULL, 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 |
<실행결과>