整理日: 2015年2月16日app
首先介紹內存映射文件操做------函數的用法以及前後執行順序函數
// 第一步:建立文件 HANDLE hFile = CreateFileForMapping(_T("MyMemFile.dat"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(hFile != 0); // 第二步:建立內存映射文件對象 HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 1024, _T("MyMapppingFile")); ASSERT(hMapFile != 0); // 第三步:獲取內存映射文件對象視圖 BYTE* pData = (BYTE*)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 1024); ASSERT(pData != NULL); // 對 pData 指針進行讀寫操做 // ...... // 第四步:取消內存視圖映射 UnmapViewOfFile(pData); // 第五步:關閉內存映射對象句柄 CloseHandle(hMapFile); // 第六步:關閉文件句柄 CloseHandle(hFile);
header file指針
// MapFile.h : header file #if !defined(AFX_MAPFILE_H__D067E5C8_C4D7_4569_A6BB_9D651FB3F396__INCLUDED_) #define AFX_MAPFILE_H__D067E5C8_C4D7_4569_A6BB_9D651FB3F396__INCLUDED_ #if _MSC_VER < 1000 #pragma once #endif // _MSC_VER < 1000 ///////////////////////////////////////////////////////////////////////////// // CMapFile class 使用說明: // 1 一個對象,打開文件映射以後,當即處理,處理完以後才能再用它打開另外一個文件映射 class CMapFile { public: CMapFile(); // protected constructor used by dynamic creation virtual ~CMapFile(); // Attributes PVOID m_pvFile; BOOL m_bSmooth; // 爲TRUE表示不阻塞,即不彈出任何對話框 private: HANDLE hFileMap; // Operations public: BOOL OpenMapFile(CString sFile); // Implementation BOOL CloseMapFile(); }; // {{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_MAPFILE_H__D067E5C8_C4D7_4569_A6BB_9D651FB3F396__INCLUDED_)
cpp filecode
// MapFile.cpp : implementation file #include "stdafx.h" #include "MapFile.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // CMapFile CMapFile::CMapFile() { m_pvFile = NULL; m_bSmooth = FALSE; } CMapFile::~CMapFile() { if (NULL != m_pvFile) { UnmapViewOfFile(m_pvFile); m_pvFile = NULL; } } // CMapFile operation handlers // 空文件會彈出 map could not be opened,在裏面敲一個回車,就行了 BOOL CMapFile::OpenMapFile(CString sFile) { if (NULL != m_pvFile) { UnmapViewOfFile(m_pvFile); // 在當前應用程序的內存地址空間解除對一個文件映射對象的映射 m_pvFile = NULL; } // 1:建立或打開一個文件內核對象: Open the file for reading and writing. // 這裏CreateFile函數的參數,路徑不管是否有空格都不能有引號,有引號的時候會出錯。 HANDLE hFile = CreateFile(sFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // 因爲hFile即便爲INVALID_HANDLE_VALUE,下面的CreateFileMapping仍然能夠正常運行, // 因此這裏必定要對hFile進行檢查! if (hFile == INVALID_HANDLE_VALUE) { if (!m_bSmooth) // 爲TRUE表示不阻塞,即不彈出任何對話框 { AfxMessageBox(_T("File[") + sFile + _T("]could not be opened. Maybe it's not exist.")); } return FALSE; } // 2:建立一個文件映射內核對象 DWORD dwFileSize = GetFileSize(hFile, NULL); // 獲取文件大小=文件長度+(WCHAR)'\0'(ssume the whole file can be mapped) // 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. hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwFileSize + 1, /* sizeof(WCHAR)==2,sizeof(char)==1 */ // 由於咱們要在文件的末尾加上一個字符串的結束符'\0', 當咱們將這個文件映射到內存中時, // 咱們就能夠像操做字符串同樣地來操做文件了。 // 若是該文件小於設定的大小,本函數將擴展該文件的大小,使磁盤上的文件變大。 // 這樣當之後將該文件做爲內存映射 文件使用時,物理存儲器就已經存在了。 NULL // 這個文件映射對象的名字用於與其餘進程共享該對象,這裏咱們還用不到。 ); if (hFileMap == NULL) { if (!m_bSmooth) { AfxMessageBox(_T("File[") + sFile + _T("] map could not be opened. May be it's empty.")); } return FALSE; } // 3:將文件數據映射到進程的地址空間: // 當建立了一個文件映射對象以後,仍然必須讓系統爲文件的數據保留一個地址空間區域, // 並將文件的數據做爲映射到該區域的物理存儲器進行提交。 m_pvFile = MapViewOfFile(hFileMap, /* FILE_MAP_WRITE */ FILE_MAP_READ, 0, 0, 0); // 獲取映射文件在內存中的首地址 // CloseHandle(hFileMap);// 關閉內存映射對象句柄 if (m_pvFile == NULL) { if (!m_bSmooth) { AfxMessageBox(_T("Could not map view of file[") + sFile + _T("].")); } return FALSE; } // 4:既然咱們經過pvFile獲得了映象視圖的起始地址,那麼能夠對視圖作一些操做了: // ANSI版本: // PSTR pchANSI = (PSTR) m_pvFile; // UNICODE版本: // PWSTR pchUnicode = (PWSTR) pvFile;如char* sz=(char*)m_pvFile;sz[dwFileSize/sizeof(char)]='\0'; // 5:從進程的地址空間中撤銷文件數據的映象: // UnmapViewOfFile(m_pvFile); // 封裝爲類,映象要在其餘地方使用因此這句話要去掉 // 6:關閉文件映射對象和文件對象: // CloseHandle(hFileMap); // 咱們改變了文件的長度,所以要從新設置文件的結束符以刪除留在文件尾部的多餘內容(好比刪除咱們先前加到文件末尾的'\0'字符) SetFilePointer(hFile, dwFileSize, NULL, FILE_BEGIN); SetEndOfFile(hFile); // 設定當前文件指針所在處爲文件結束處.該處後面的內容將被刪除 CloseHandle(hFile); return TRUE; } BOOL CMapFile::CloseMapFile() { if (NULL != m_pvFile) { // 取消內存視圖映射 if (UnmapViewOfFile(m_pvFile)) { m_pvFile = NULL; CloseHandle(hFileMap); // 關閉內存映射對象句柄 return TRUE; } return FALSE; } return TRUE; }