若要使用內(nèi)存映射文件,必須執(zhí)行下列操作步驟: 1) 創(chuàng)建或打開一個(gè)文件內(nèi)核對(duì)象,,該對(duì)象用于標(biāo)識(shí)磁盤上你想用作內(nèi)存映射文件的文件,。 2) 創(chuàng)建一個(gè)文件映射內(nèi)核對(duì)象,告訴系統(tǒng)該文件的大小和你打算如何訪問(wèn)該文件,。 3) 讓系統(tǒng)將文件映射對(duì)象的全部或一部分映射到你的進(jìn)程地址空間中,。 當(dāng)完成對(duì)內(nèi)存映射文件的使用時(shí),,必須執(zhí)行下面這些步驟將它清除: 1) 告訴系統(tǒng)從你的進(jìn)程的地址空間中撤消文件映射內(nèi)核對(duì)象的映像。 2) 關(guān)閉文件映射內(nèi)核對(duì)象,。 3) 關(guān)閉文件內(nèi)核對(duì)象,。
下面將詳細(xì)介紹這些操作步驟。 步驟1:創(chuàng)建或打開文件內(nèi)核對(duì)象 HANDLE CreateFile( PCSTR pszFileName, DWORD dwDesiredAccess, DWORD dwShareMode, PSECURITY_ATTRIBUTES psa, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); dwDesiredAccess的值
dwShareMode 的值
步驟2:創(chuàng)建一個(gè)文件映射內(nèi)核對(duì)象 調(diào)用CreateFileMapping函數(shù)告訴系統(tǒng),,文件映射對(duì)象需要多少物理存儲(chǔ)器,。 HANDLE CreateFileMapping( HANDLE hFile, PSECURITY_ATTRIBUTES psa, DWORD fdwProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, PCTSTR pszName);
第一個(gè)參數(shù):hFile用于標(biāo)識(shí)你想要映射到進(jìn)程地址空間中的文件句柄。該句柄由前面調(diào)用的CreateFile函數(shù)返回,。 第二個(gè)參數(shù):psa參數(shù)是指向文件映射內(nèi)核對(duì)象的SECURITY_ATTRIBUTES結(jié)構(gòu)的指針,,通常傳遞的值是NULL(它提供默認(rèn)的安全特性,返回的句柄是不能繼承的),。 第三個(gè)參數(shù):fdwProtect參數(shù)使你能夠設(shè)定這些保護(hù)屬性,。大多數(shù)情況下,可以設(shè)定下表列出的3個(gè)保護(hù)屬性之一,。 使用fdwProtect 參數(shù)設(shè)定的部分保護(hù)屬性
除了上面的頁(yè)面保護(hù)屬性外,,還有4個(gè)節(jié)保護(hù)屬性
節(jié)的第一個(gè)保護(hù)屬性是SEC_NOCACHE,,它告訴系統(tǒng),沒有將文件的任何內(nèi)存映射頁(yè)面放入高速緩存,。因此,,當(dāng)將數(shù)據(jù)寫入該文件時(shí),系統(tǒng)將更加經(jīng)常地更新磁盤上的文件數(shù)據(jù),。供設(shè)備驅(qū)動(dòng)程序開發(fā)人員使用的,,應(yīng)用程序通常不使用。 節(jié)的第二個(gè)保護(hù)屬性是SEC_IMAGE,,它告訴系統(tǒng),,你映射的文件是個(gè)可移植的可執(zhí)行(PE)文件映像。當(dāng)系統(tǒng)將該文件映射到你的進(jìn)程的地址空間中時(shí),系統(tǒng)要查看文件的內(nèi)容,,以確定將哪些保護(hù)屬性賦予文件映像的各個(gè)頁(yè)面,。例如, PE文件的代碼節(jié)( . text)通常用PAGE_ EXECUTE_READ屬性進(jìn)行映射,, 而PE 文件的數(shù)據(jù)節(jié)( .data) 則通常用PAGE_READW RITE屬性進(jìn)行映射,。如果設(shè)定的屬性是S E C _ I M A G E,則告訴系統(tǒng)進(jìn)行文件映像的映射,,并設(shè)置相應(yīng)的頁(yè)面保護(hù)屬性,。 最后兩個(gè)保護(hù)屬性是SEC_RESERVE和SEC_COMMIT,,它們是兩個(gè)互斥屬性,。只有當(dāng)創(chuàng)建由系統(tǒng)的頁(yè)文件支持的文件映射對(duì)象時(shí),這兩個(gè)標(biāo)志才有意義,。SEC_COMMIT標(biāo)志能使CreateFileMapping從系統(tǒng)的頁(yè)文件中提交存儲(chǔ)器,。如果兩個(gè)標(biāo)志都不設(shè)定,其結(jié)果也一樣,。 第四和五個(gè)參數(shù):dwMaximumSizeHigh和dwMaximumSizeLow這兩個(gè)參數(shù)將告訴系統(tǒng)該文件的最大字節(jié)數(shù) 最后一個(gè)參數(shù)是pszName: 它是個(gè)以0結(jié)尾的字符串,,用于給該文件映射對(duì)象賦予一個(gè)名字。該名字用于與其他進(jìn)程共享文件映射對(duì)象,。
步驟3:將文件數(shù)據(jù)映射到進(jìn)程的地址空間 將文件的數(shù)據(jù)作為映射到該區(qū)域的物理存儲(chǔ)器進(jìn)行提交,。 PVOID MapViewOfFile( HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap);
第一個(gè)參數(shù):hFileMappingObject用于標(biāo)識(shí)文件映射對(duì)象的句柄,該句柄是前面調(diào)用CreateFileMapping或OpenFileMapping函數(shù)返回的,。
第二個(gè)參數(shù):dwDesiredAccess用于標(biāo)識(shí)如何訪問(wèn)該數(shù)據(jù),。可以設(shè)定下表所列的4個(gè)值中的一個(gè),。
(一個(gè)文件映射到你的進(jìn)程的地址空間中時(shí),你不必一次性地映射整個(gè)文件,。相反,,可以只將文件的一小部分映射到地址空間。被映射到進(jìn)程的地址空間的這部分文件稱為一個(gè)視圖。)
第三四個(gè)參數(shù):dwFileOfsetHigh和dwFileOfsetLow參數(shù),。指定哪個(gè)字節(jié)應(yīng)該作為視圖中的第一個(gè)字節(jié)來(lái)映射,。 第五個(gè)參數(shù):dwNumberOfBytesToMap有多少字節(jié)要映射到地址空間。如果設(shè)定的值是0,,那么系統(tǒng)將設(shè)法把從文件中的指定位移開始到整個(gè)文件的結(jié)尾的視圖映射到地址空間,。
步驟4:從進(jìn)程的地址空間中撤消文件數(shù)據(jù)的映像 當(dāng)不再需要保留映射到進(jìn)程地址空間區(qū)域中的文件數(shù)據(jù)時(shí),可以通過(guò)調(diào)用下面的函數(shù)將它釋放: BOOL UnmapViewOfFile(PVOID pvBaseAddress); 參數(shù):pvBaseAddress由MapViewOfFile函數(shù)返回,。 注意:如果沒有調(diào)用這個(gè)函數(shù),,那么在進(jìn)程終止運(yùn)行前,保留的區(qū)域就不會(huì)被釋放,。每當(dāng)調(diào)用MapViewOfFile時(shí),,系統(tǒng)總是在你的進(jìn)程地址空間中保留一個(gè)新區(qū)域,而以前保留的所有區(qū)域?qū)⒉槐会尫拧?/p> 為了提高速度,,系統(tǒng)將文件的數(shù)據(jù)頁(yè)面進(jìn)行高速緩存,,并且在對(duì)文件的映射視圖進(jìn)行操作時(shí)不立即更新文件的磁盤映像。如果需要確保你的更新被寫入磁盤,,可以強(qiáng)制系統(tǒng)將修改過(guò)的數(shù)據(jù)的一部分或全部重新寫入磁盤映像中,,方法是調(diào)用FlushViewOfFile函數(shù): BOOL FlushViewOfFile( PVOID pvAddress, SIZE_T dwNumberOfBytesToFlush); 第一個(gè)參數(shù)是包含在內(nèi)存映射文件中的視圖的一個(gè)字節(jié)的地址。該函數(shù)將你在這里傳遞的地址圓整為一個(gè)頁(yè)面邊界值,。 第二個(gè)參數(shù)用于指明你想要刷新的字節(jié)數(shù),。系統(tǒng)將把這個(gè)數(shù)字向上圓整,使得字節(jié)總數(shù)是頁(yè)面的整數(shù),。如果你調(diào)用FlushViewOfFile函數(shù)并且不修改任何數(shù)據(jù),,那么該函數(shù)只是返回,而不將任何信息寫入磁盤,。
步驟5和步驟6:關(guān)閉文件映射對(duì)象和文件對(duì)象 用CloseHandle函數(shù)關(guān)閉相應(yīng)的對(duì)象,。 在代碼開始運(yùn)行時(shí)關(guān)閉這些對(duì)象: HANDLE hFile = CreateFile(...); HANDLE hFileMapping = CreateFileMapping(hFile, ...); CloseHandle(hFile); PVOID pvFile = MapViewOfFile(hFileMapping, ...); CloseHandle(hFileMapping);
// Use the memory-mapped file.
UnmapViewOfFile(pvFile); |
|