導航:首頁 > 文件教程 > 內存映射文件實例

內存映射文件實例

發布時間:2024-04-17 17:50:16

『壹』 鍐呭瓨鏄犲皠鏂囦歡鐨勫簲鐢ㄧず渚

涓嬮潰緇撳悎涓涓鍏蜂綋鐨勫疄渚嬫潵榪涗竴姝ヨ茶堪鍐呭瓨鏄犲皠鏂囦歡鐨勪嬌鐢ㄦ柟娉曘傝ュ疄渚嬩粠絝鍙f帴鏀舵暟鎹錛屽苟瀹炴椂灝嗗叾瀛樻斁浜庣佺洏錛岀敱浜庢暟鎹閲忓ぇ錛堝嚑鍗丟B錛夛紝鍦ㄦら夌敤鍐呭瓨鏄犲皠鏂囦歡榪涜屽勭悊銆備笅闈㈢粰鍑虹殑鏄浣嶄簬宸ヤ綔綰跨▼MainProc涓鐨勯儴鍒嗕富瑕佷唬鐮侊紝璇ョ嚎紼嬭嚜紼嬪簭榪愯屾椂鍚鍔錛屽綋絝鍙f湁鏁版嵁鍒拌揪鏃跺皢浼氬彂鍑轟簨浠秇Event[0]錛學aitForMultipleObjects錛堬級鍑芥暟絳夊緟鍒拌ヤ簨浠跺彂鐢熷悗灝嗘帴鏀跺埌鐨勬暟鎹淇濆瓨鍒扮佺洏錛屽傛灉緇堟㈡帴鏀跺皢鍙戝嚭浜嬩歡hEvent[1]錛屼簨浠跺勭悊榪囩▼灝嗚礋璐e畬鎴愯祫婧愮殑閲婃斁鍜屾枃浠剁殑鍏抽棴絳夊伐浣溿備笅闈㈢粰鍑烘ょ嚎紼嬪勭悊鍑芥暟鐨勫叿浣撳疄鐜拌繃紼嬶細
// 鍒涘緩鏂囦歡鍐呮牳瀵硅薄錛屽叾鍙ユ焺淇濆瓨浜巋File
HANDLE hFile = CreateFile(Recv1.zip,GENERIC_WRITE | GENERIC_READ,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
// 鍒涘緩鏂囦歡鏄犲皠鍐呮牳瀵硅薄錛屽彞鏌勪繚瀛樹簬hFileMapping
HANDLE hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0x4000000,NULL);
// 閲婃斁鏂囦歡鍐呮牳瀵硅薄
CloseHandle(hFile);
// 璁懼畾澶у皬銆佸嚲縐婚噺絳夊弬鏁 // 灝介噺鎶婃枃浠惰劇疆澶т竴浜涳紝 濡傛灉鍐欑殑鏁版嵁瓚呰繃錛岃懼畾鐨勫礆紝鍐嶆℃槧灝勬枃浠朵細鎶ラ敊 getlasterror = 183;
__int64 qwFileSize = 0x4000000;
__int64 qwFileOffset = 0;
__int64 T = 600 * sinf.dwAllocationGranularity;
DWORD dwBytesInBlock = 1000 * sinf.dwAllocationGranularity;
// 灝嗘枃浠舵暟鎹鏄犲皠鍒拌繘紼嬬殑鍦板潃絀洪棿
PBYTE pbFile = (PBYTE)MapViewOfFile(hFileMapping,FILE_MAP_ALL_ACCESS,(DWORD)(qwFileOffset>>32),(DWORD)(qwFileOffset&0xFFFFFFFF),dwBytesInBlock);
while(bLoop)
{
// 鎹曡幏浜嬩歡hEvent[0]鍜屼簨浠秇Event[1]
DWORD ret = WaitForMultipleObjects(2,hEvent,FALSE,INFINITE);
ret -= WAIT_OBJECT_0;
switch (ret)
{
// 鎺ユ敹鏁版嵁浜嬩歡瑙﹀彂
case 0:
// 浠庣鍙f帴鏀舵暟鎹騫朵繚瀛樺埌鍐呭瓨鏄犲皠鏂囦歡
nReadLen=syio_Read(port[1],pbFile + qwFileOffset,QueueLen);
qwFileOffset += nReadLen;
// 褰撴暟鎹鍐欐弧60%鏃訛紝涓洪槻鏁版嵁婧㈠嚭錛岄渶瑕佸湪鍏跺悗寮杈熶竴鏂扮殑鏄犲皠瑙嗗浘
if (qwFileOffset > T)
{
T = qwFileOffset + 600 * sinf.dwAllocationGranularity;UnmapViewOfFile(pbFile);
pbFile = (PBYTE)MapViewOfFile(hFileMapping,FILE_MAP_ALL_ACCESS,(DWORD)(qwFileOffset>>32),(DWORD)(qwFileOffset&0xFFFFFFFF),dwBytesInBlock);
}
break;
// 緇堟浜嬩歡瑙﹀彂
case 1:
bLoop = FALSE;
// 浠庤繘紼嬬殑鍦板潃絀洪棿鎾ゆ秷鏂囦歡鏁版嵁鏄犲儚
UnmapViewOfFile(pbFile);
// 鍏抽棴鏂囦歡鏄犲皠瀵硅薄
CloseHandle(hFileMapping);
break;
}
}鈥
鍦ㄧ粓姝浜嬩歡瑙﹀彂澶勭悊榪囩▼涓濡傛灉鍙綆鍗曠殑鎵ц孶nmapViewOfFile錛堬級鍜孋loseHandle錛堬級鍑芥暟灝嗘棤娉曟g『鏍囪瘑鏂囦歡鐨勫疄闄呭ぇ灝忥紝鍗沖傛灉寮杈熺殑鍐呭瓨鏄犲皠鏂囦歡涓30GB錛岃屾帴鏀剁殑鏁版嵁鍙鏈14GB錛岄偅涔堜笂榪扮▼搴忔墽琛屽畬鍚庯紝淇濆瓨鐨勬枃浠墮暱搴︿粛鏄30GB銆備篃灝辨槸璇達紝鍦ㄥ勭悊瀹屾垚鍚庤繕瑕佸啀嬈¢氳繃鍐呭瓨鏄犲皠鏂囦歡鐨勫艦寮忓皢鏂囦歡鎮㈠嶅埌瀹為檯澶у皬錛屼笅闈㈡槸瀹炵幇姝よ佹眰鐨勪富瑕佷唬鐮侊細
// 鍒涘緩鍙﹀栦竴涓鏂囦歡鍐呮牳瀵硅薄
hFile2 = CreateFile(Recv.zip,GENERIC_WRITE | GENERIC_READ,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
// 浠ュ疄闄呮暟鎹闀垮害鍒涘緩鍙﹀栦竴涓鏂囦歡鏄犲皠鍐呮牳瀵硅薄
hFileMapping2 = CreateFileMapping(hFile2,NULL,PAGE_READWRITE,0,(DWORD)(qwFileOffset&0xFFFFFFFF),NULL);
// 鍏抽棴鏂囦歡鍐呮牳瀵硅薄
CloseHandle(hFile2);
// 灝嗘枃浠舵暟鎹鏄犲皠鍒拌繘紼嬬殑鍦板潃絀洪棿
pbFile2 = (PBYTE)MapViewOfFile(hFileMapping2,FILE_MAP_ALL_ACCESS,0,0,qwFileOffset);
// 灝嗘暟鎹浠庡師鏉ョ殑鍐呭瓨鏄犲皠鏂囦歡澶嶅埗鍒版ゅ唴瀛樻槧灝勬枃浠
memcpy(pbFile2,pbFile,qwFileOffset);
file:
//浠庤繘紼嬬殑鍦板潃絀洪棿鎾ゆ秷鏂囦歡鏁版嵁鏄犲儚
UnmapViewOfFile(pbFile);
UnmapViewOfFile(pbFile2);
// 鍏抽棴鏂囦歡鏄犲皠瀵硅薄
CloseHandle(hFileMapping);
CloseHandle(hFileMapping2);
// 鍒犻櫎涓存椂鏂囦歡
DeleteFile(Recv1.zip);

『貳』 內存映射文件 存儲空間不夠、

設一個偏移量,不要映射那麼多。下面是別人的處理方法,抄來給你:

使用內存映射文件處理大文件的代碼示例:

1 SYSTEM_INFO sinf;
2 GetSystemInfo(&sinf);
3
4 // Open the file for reading and writing.
5 HANDLE hFile = CreateFile(pszPathname, GENERIC_WRITE | GENERIC_READ, 0,
6 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
7 if (hFile == INVALID_HANDLE_VALUE) {
8 chMB("File could not be opened.");
9 return(FALSE);
10 }
11
12 // Get the size of the file (I assume the whole file can be mapped) in bytes.
13 DWORD dwFileSize = GetFileSize(hFile, NULL);
14
15 // Create the file-mapping object.
16 HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE,
17 0, dwFileSize, NULL);
18 if (hFileMap == NULL) {
19 chMB("File map could not be opened.");
20 CloseHandle(hFile);
21 return(FALSE);
22 }
23
24 DWORD map_data_offset = 0;
25 DWORD bytes_mapped = sinf.dwAllocationGranularity;
26 PVOID pvFile = NULL;
27 PSTR ps_ptr = NULL;
28
29 while(dwFileSize > 0)
30 {
31 if(dwFileSize < bytes_mapped)
32 {
33 pvFile = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, map_data_offset, dwFileSize);
34 //對字元數組pvFile的處理
35 map_data_offset += dwFileSize;
36 dwFileSize = 0;
37 }
38 else
39 {
40 pvFile = MapViewOfFile(hFileMap,FILE_MAP_WRITE,0,map_data_offset,bytes_mapped);
41 //對字元數組pvFile的處理
42 map_data_offset += bytes_mapped;
43 dwFileSize -= bytes_mapped;
44 }
45 }
46 // Clean up everything before exiting.
47 UnmapViewOfFile(pvFile);
48 CloseHandle(hFileMap);
49 // Remove trailing zero character added earlier.
50 SetFilePointer(hFile, dwFileSize, NULL, FILE_BEGIN);
51 CloseHandle(hFile);
文件映射對象存儲於內核地址范圍是所有操作系統的進程共享的,而MapViewOfFile文件映射地址空間是存在於進程的私有地址空間中,要想指定地址空間首地址可用MapViewOfFileEx函數,但只是建議首地址。

『叄』 怎樣用C++內存映射磁碟文件的方式映射一個幾百M的文件,還有幾十M,還有幾十K的文件

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
int main()
{
HANDLE hFile = CreateFile(_T("1.txt"), GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if (hFile == INVALID_HANDLE_VALUE) {
puts("fail to create file");
goto fail_open;
}

SetFileValidData(hFile, 1024);

HANDLE hMap = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, 1024, 0);
if (hMap == NULL) {
puts("fail to create mapping");
goto fail_map;
}

LPVOID pContent = MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 1024);
if (pContent == 0) {
puts("fail to open mapping");
goto fail_view;
}

//好了,此時這個文件就相當於你用malloc申請的一個1024位元組的內存空間。
char* pStr = (char*) pContent;
strcpy(pStr, "hahaha");

UnmapViewOfFile(pContent);
fail_view:
CloseHandle(hMap);
fail_map:
CloseHandle(hFile);
fail_open:
return 0;
}

『肆』 我c++要處理大量數據,一個都是幾百m,如何存入內存.

用內存映射應該行的。內存映射就是把一個文件當作一塊內存區域用。

類別: 內存映射文件

題目:對一個文件使用內存映射文件

Demo:

1:創建或打開一個文件內核對象:

// Open the file for reading and writing.
HANDLE hFile = CreateFile(pszPathname, GENERIC_WRITE | GENERIC_READ, 0,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

// 由於hFile即使為INVALID_HANDLE_VALUE,下面的CreateFileMapping仍然可以正常運行,
// 所以這里一定要對hFile進行檢查!
if (hFile == INVALID_HANDLE_VALUE) {
chMB("File could not be opened.");
return(FALSE);
}

2:創建一個文件映射內核對象:

// Get the size of the file (I assume the whole file can be mapped).
DWORD dwFileSize = GetFileSize(hFile, NULL);

// Create the file-mapping object. The file-mapping object is 1 character
// bigger than the file size so that a zero character can be placed at the
// end of the file to terminate the string (file). Because I don't yet know
// if the file contains ANSI or Unicode characters, I assume worst case
// and add the size of a WCHAR instead of CHAR.
HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE,
0,
dwFileSize + sizeof(WCHAR), // 如果該文件小於設定的大小,本函數將擴展該文件的大小,
// 使磁碟上的文件變大。這樣當以後將該文件作為內存映射
// 文件使用時,物理存儲器就已經存在了。
NULL f// 這個文件映射對象的名字用於與其他進程共享該對象,這里我們還用不到。
);

if (hFileMap == NULL) {
chMB("File map could not be opened.");
CloseHandle(hFile);
return(FALSE);
}

3:將文件數據映射到進程的地址空間:
當創建了一個文件映射對象之後,仍然必須讓系統為文件的數據保留一個地址空間區域,
並將文件的數據作為映射到該區域的物理存儲器進行提交。

// Get the address where the first byte of the file is mapped into memory.
// the return value is the starting address of the mapped view:
PVOID pvFile = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);

if (pvFile == NULL) {
chMB("Could not map view of file.");
CloseHandle(hFileMap);
CloseHandle(hFile);
return(FALSE);
}

4:既然我們通過pvFile得到了映象視圖的起始地址,那麼可以對視圖做一些操作了:

ANSI版本:
PSTR pchANSI = (PSTR) pvFile;
UNICODE版本:
PWSTR pchUnicode = (PWSTR) pvFile;

5:從進程的地址空間中撤銷文件數據的映象:

// Clean up everything before exiting.
UnmapViewOfFile(pvFile);

6:關閉文件映射對象和文件對象:

CloseHandle(hFileMap);
CloseHandle(hFile);

Definition:

HANDLE CreateFileMapping(
HANDLE hFile, // handle to file
LPSECURITY_ATTRIBUTES lpAttributes, // security
DWORD flProtect, // protection
DWORD dwMaximumSizeHigh, // high-order DWORD of size
DWORD dwMaximumSizeLow, // low-order DWORD of size
LPCTSTR lpName // object name
);
LPVOID MapViewOfFile(
HANDLE hFileMappingObject, // handle to file-mapping object
DWORD dwDesiredAccess, // access mode
DWORD dwFileOffsetHigh, // high-order DWORD of offset
DWORD dwFileOffsetLow, // low-order DWORD of offset
SIZE_T dwNumberOfBytesToMap // number of bytes to map
);
BOOL UnmapViewOfFile(
LPCVOID lpBaseAddress // starting address
);

Tips:
也可以盡量早地把對象關閉,以消除資源泄漏的可能性,如:
HANDLE hFile = CreateFile(...);
HANDLE hFileMapping = CreateFileMapping(hFile,...);
CloseHandle(hFile);

PVOID pvFile = MapViewOfFile(hFileMapping,...);
CloseHandle(hFileMapping);

// use the memory-mapped file.

UnmapViewOfFile(pvFile);

閱讀全文

與內存映射文件實例相關的資料

熱點內容
蘋果換機數據遷移包含哪些數據 瀏覽:234
程式控制可編程直流電源在哪裡 瀏覽:598
容積長寬高的數據從什麼面測量 瀏覽:978
蘋果手游工作室 瀏覽:362
數據型號特別多怎麼合並 瀏覽:600
企業微信電腦版怎麼無法接受文件 瀏覽:968
微信個人相冊怎麼隱藏 瀏覽:368
上傳文件時怎麼獲取文件全路徑 瀏覽:955
linuxjs讀取文件 瀏覽:104
exe後綴的pdf文件 瀏覽:381
win8升級到專業版 瀏覽:487
快圖瀏覽quickpiciphone 瀏覽:847
app線稿圖需要哪些要求 瀏覽:752
java只能輸入漢字 瀏覽:630
java定義char 瀏覽:133
excel2007插入壓縮文件 瀏覽:70
怎麼設定自己公司的網站 瀏覽:324
如何在辦公軟體上直接復制文件 瀏覽:939
c語言程序設計矩陣運算 瀏覽:894
影響網路質量因素有哪些 瀏覽:587

友情鏈接