FileMapping使用者類原始碼(原創, 歡迎批評指正) (轉)
歡迎指正
// uc_filemap.h: interface for the UC_FILEMAPPING class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_UC_FILEMAPPING_H__72FE31B2_7B02_442F_A754_66427E1C5946__INCLUDED_)
#define AFX_UC_FILEMAPPING_H__72FE31B2_7B02_442F_A754_66427E1C5946__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//////////////////////////////////////////////////
// 模組: 對映類
// 作者: 張旻
// 建立: 2002.01.16
// 說明:
// 利用記憶體對映檔案進行程式之間的記憶體共享,
// 目前的32位應用定址範圍4GB, 不需要高位
//////////////////////////////////////////////////
#include "uc_log.h"
//自定義返回值
#define RET_FILEOPENNED RET_USER + 1 //檔案已經開啟
#define RET_FILENOTOPENNED RET_USER + 2 //檔案未開啟
#define RET_BUFFERTOOBIG RET_USER + 3 //緩衝區過大
#define RET_BUFFEROVERFLOW RET_USER + 4 //緩衝區
#define RET_FILEPROCESSING RET_USER + 5 //檔案正在操作
#define RET_OFFSETOVERFLOW RET_USER + 6 //偏移量溢位
//共享記憶體的預留長度資訊結構預定義
typedef struct tagMnfo{
D dwSizeHigh; //高位檔案大小
DWORD dwSizeLow; //低位檔案大小
DWORD dwSizeUsedHigh; //高位使用大小
DWORD dwSizeUsedLow; //低位使用大小
char szMappiame[_MAX_PATH]; //對映名稱
tagMapInfo()
{
dwSizeHigh = dwSizeLow = dwSizeUsedHigh = dwSizeUsedLow = 0;
memset( szMappingName, 0, _MAX_PATH );
}
}US_MAPINFO, *PUS_MAPINFO;
//分頁門限
#define HIGH_MAX 0xFFFFFFFE //高位最大值
#define LOW_MAX 0xFFFFFFFF - sizeof(US_MAPINFO) //低位最大值
#define INFO_LEN sizeof(US_MAPINFO) //頭資訊長度
#define NOPHYSICALFILE 0xFFFFFFFF //不需要物理檔案
class UC_FILEMAPPING : public UC_LOG
{
public:
//////////////////////////////////////////////////
// 作者: 張旻
// 建立: 2002.01.16
// 功能: 獲得檔案使用大小
// 引數:
// 返回:
// 檔案使用大小
//////////////////////////////////////////////////
DWORD GetSizeUsed();
//////////////////////////////////////////////////
// 作者: 張旻
// 建立: 2002.01.16
// 功能: 獲得檔案大小
// 引數:
// 返回:
// 檔案大小
//////////////////////////////////////////////////
DWORD GetSize();
//////////////////////////////////////////////////
// 作者: 張旻
// 建立: 2002.01.16
// 功能: 寫入對映檔案
// 引數:
// [in] lpBuf 緩衝區
// [in] nSize 緩衝區大小
// [in] dwOffsetLow 偏移地址地位
// [in] isAppend 追加寫入
// 返回:
// RET_BADARG 引數
// RET_BUFFERTOBIG 快取區過大
// RET_BUFFEROVERFLOW 緩衝區溢位
// RET_FILENOTOPENNED 檔案未開啟
// RET_FILEPROCESSING 檔案正在操作
// RET_FILEERR 檔案操作失敗
// RET_OK 操作成功
//////////////////////////////////////////////////
DWORD Write( LPVOID lpBuf, UINT &nSize, DWORD dwOffsetLow=0, BOOL isAppend=TRUE );
//////////////////////////////////////////////////
// 作者: 張旻
// 建立: 2002.01.16
// 功能: 讀取對映檔案
// 引數:
// [in] lpBuf 緩衝區
// [in] nSize 緩衝區大小
// [in] dwOffsetLow 偏移地址地位
// 返回:
// RET_BADARG 引數非法
// RET_BUFFERTOBIG 快取區過大
// RET_BUFFEROVERFLOW 緩衝區溢位
// RET_FILENOTOPENNED 檔案未開啟
// RET_FILEPROCESSING 檔案正在操作
// RET_FILEERR 檔案操作失敗
// RET_OK 操作成功
//////////////////////////////////////////////////
DWORD Read( LPVOID lpszBuf, UINT &nSize, DWORD dwOffsetLow=0 );
//////////////////////////////////////////////////
// 作者: 張旻
// 建立: 2002.01.16
// 功能: 關閉對映檔案
// 引數:
// [in] wantDump 需要匯出
// 返回:
// RET_FILENOTOPENNED 檔案未開啟
// RET_FILEERR 檔案操作失敗
// RET_OK 操作成功
//////////////////////////////////////////////////
DWORD Close( BOOL wantDump=TRUE );
//////////////////////////////////////////////////
// 作者: 張旻
// 建立: 2002.01.16
// 功能: 開啟對映檔案
// 引數:
// [in] lpszMappingName 對映記憶體命名
// 返回:
// RET_BADARG 引數非法
// RET_FILEOPENNED 檔案已經開啟
// RET_FILEERR 檔案操作失敗
// RET_OK 操作成功
//////////////////////////////////////////////////
DWORD Open( LPCTSTR lpszMappingName );
//////////////////////////////////////////////////
// 作者: 張旻
// 建立: 2002.01.16
// 功能: 開啟對映檔案
// 引數:
// [in] lpszFilePath 物理檔案路徑
// [in] lpszMappingName 對映記憶體命名
// [in] dwSizeLow 低位空間大小
// 返回:
// RET_BADARG 引數非法
// RET_FILEOPENNED 檔案已經開啟
// RET_FILEERR 檔案操作失敗
// RET_OK 操作成功
//////////////////////////////////////////////////
DWORD Open( LPCTSTR lpszFilePath, LPCTSTR lpszMappingName, DWORD dwSizeLow );
//////////////////////////////////////////////////
// 作者: 張旻
// 建立: 2002.01.16
// 功能: 構造
//////////////////////////////////////////////////
UC_FILEMAPPING();
//////////////////////////////////////////////////
// 作者: 張旻
// 建立: 2002.01.16
// 功能: 解構函式
//////////////////////////////////////////////////
virtual ~UC_FILEMAPPING();
protected:
HANDLE m_hPhysicile; //物理檔案控制程式碼
HANDLE m_hMappingFile; //對映檔案控制程式碼
HANDLE m_hFileOP; //檔案操作互斥量
LPVOID m_lpCursor; //對映遊標地址指標
LPVOID m_lpAddress; //對映檔案地址指標
PUS_MAPINFO m_pusMapInfo; //對映記憶體頭資訊
BOOL m_isFileLoaded; //工作狀態標誌
BOOL m_isMyHandle; //是否是自己建立的檔案對映
DWORD m_dwSysAlloc; //分配記憶體的最小單位
private:
DWORD FlushView();
DWORD GetErrorMessage();
//////////////////////////////////////////////////
// 作者: 張旻
// 建立: 2002.01.16
// 功能: 格式化大小和偏移量
// 引數:
// [in] dwOffsetLow 低位偏移量
// 返回:
// RET_BADARG 引數非法
// RET_FILENOTOPENNED 檔案未開啟
// RET_FILEPROCESSING 檔案正在操作
// RET_OK 操作成功
//////////////////////////////////////////////////
//////////////////////////////////////////////////
// 作者: 張旻
// 建立: 2002.01.16
// 功能: 移動對映檔案指標
// 引數:
// [in] dwOffsetLow 低位偏移量
// 返回:
// RET_BADARG 引數非法
// RET_FILENOTOPENNED 檔案未開啟
// RET_FILEPROCESSING 檔案正在操作
// RET_OK 操作成功
//////////////////////////////////////////////////
};
#endif // !defined(AFX_UC_FILEMAPPING_H__72FE31B2_7B02_442F_A754_66427E1C5946__INCLUDED_)
// uc_filemapping.cpp: implementation of the UC_FILEMAPPING class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "uc_filemapping.h"
#ifdef _DE
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//建構函式
UC_FILEMAPPING::UC_FILEMAPPING()
{
WaitForSingle( m_hMutex, INFINITE );
//初始化控制程式碼
m_hPhysicsFile = NULL;
m_hMappingFile = NULL;
m_hFileOP = NULL;
//初始化標誌
m_isFileLoaded = FALSE;
m_isMyHandle = FALSE;
//初始化檔案成員變數
m_pusMapInfo = NULL;
m_lpAddress = NULL;
m_lpCursor = NULL;
//得到系統的最小記憶體單位
SYSTEM_INFO SysInfo;
GetSystemInfo( &SysInfo );
m_dwSysAlloc = SysInfo.dwAllocationGranularity;
ReleaseMutex( m_hMutex );
}
//解構函式
UC_FILEMAPPING::~UC_FILEMAPPING()
{
WaitForSingleObject( m_hMutex, INFINITE );
//互斥操作
WaitForSingleObject( m_hFileOP, INFINITE );
//關閉對映記憶體頭資訊指標
if ( m_pusMapInfo )
delete m_pusMapInfo;
//關閉控制程式碼
ReleaseMutex( m_hFileOP );
//只有建立者才有權關閉控制程式碼
if ( m_isMyHandle ){
CloseHandle( m_hPhysicsFile );
CloseHandle( m_hMappingFile );
CloseHandle( m_hFileOP );
}
ReleaseMutex( m_hMutex );
}
//新建檔案
DWORD UC_FILEMAPPING::Open(LPCTSTR lpszFilePath, LPCTSTR lpszMappingName, DWORD dwSizeLow)
{
//狀態監測
if ( m_isFileLoaded )
return RET_FILEOPENNED;
//引數監測
if ( lpszMappingName==NULL )
return RET_BADARG;
DWORD dwRet = RET_OK;
//建立檔案操作互斥控制程式碼
char szMutex[_MAX_PATH];
memset( szMutex, 0, _MAX_PATH );
sprintf( szMutex, "%s_MUTEX", lpszMappingName );
m_hFileOP = CreateMutex( NULL, FALSE, szMutex );
WaitForSingleObject( m_hFileOP, INFINITE );
//建立對應的物理檔案
if ( lpszFilePath!=NULL ){
//新建檔案
m_hPhysicsFile = CreateFile( lpszFilePath, GENERIC_READ|GENERIC_WRITE, 0,
NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL );
//如果檔案存在, 開啟現有檔案
if ( m_hPhysicsFile==INVALID_HANDLE_VALUE ){
GetErrorMessage();
m_hPhysicsFile = CreateFile( lpszFilePath, GENERIC_READ|GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
}
}
if ( m_hPhysicsFile==INVALID_HANDLE_VALUE ){
GetErrorMessage();
m_hPhysicsFile = NULL;
dwRet = RET_FILEERR;
}
else{
//建立對映檔案(實際長度比申請長度多頭資訊的長度)
if ( dwRet==RET_OK ){
if ( m_hPhysicsFile==NULL ){
m_hMappingFile = CreateFileMapping( (HANDLE)NOPHYSICALFILE, NULL, PAGE_READWRITE,
0, dwSizeLow, lpszMappingName );
}
else{
m_hMappingFile = CreateFileMapping( m_hPhysicsFile, NULL, PAGE_READWRITE,
0, dwSizeLow + INFO_LEN, lpszMappingName );
}
if ( m_hMappingFile==NULL ){
GetErrorMessage();
CloseHandle( m_hPhysicsFile );
m_hPhysicsFile = NULL;
dwRet = RET_FILEERR;
}
else{
//獲得對應的對映地址
m_lpAddress = MapViewOfFile( m_hMappingFile, FILE_MAP_ALL_ACCESS,
0, 0, 0 );
if ( m_lpAddress==NULL ){
dwRet = RET_FILEERR;
}
else{
//儲存對映記憶體頭資訊
if ( m_pusMapInfo==NULL )
m_pusMapInfo = new US_MAPINFO;
m_pusMapInfo->dwSizeLow = dwSizeLow + INFO_LEN;
memset( m_pusMapInfo->szMappingName, 0, _MAX_PATH );
memcpy( m_pusMapInfo->szMappingName, lpszMappingName, strlen(lpszMappingName) );
memcpy( m_lpAddress, m_pusMapInfo, INFO_LEN );
//儲存申請獲得的開始地址和初始化遊標資訊
//這裡其實真正的其實地址因為包含了頭部信
//息, 為此需要移動到空白部分
m_lpAddress = m_lpCursor = (LPVOID)( (LPBYTE)m_lpAddress + INFO_LEN );
//設定開啟標誌資訊
m_isFileLoaded = TRUE;
m_isMyHandle = TRUE;
}
}
}
}
ReleaseMutex( m_hFileOP );
if ( dwRet!=RET_OK )
CloseHandle( m_hFileOP );
return dwRet;
}
//開啟一個已有命名記憶體對映檔案
DWORD UC_FILEMAPPING::Open(LPCTSTR lpszMappingName)
{
//狀態監測
if ( m_isFileLoaded || m_hFileOP )
return RET_FILEOPENNED;
//引數監測
if ( lpszMappingName==NULL )
return RET_BADARG;
DWORD dwRet = RET_OK;
//建立檔案操作互斥控制程式碼
char szMutex[_MAX_PATH];
memset( szMutex, 0, _MAX_PATH );
sprintf( szMutex, "%s_MUTEX", lpszMappingName );
m_hFileOP = OpenMutex( MUTEX_ALL_ACCESS, FALSE, szMutex );
if ( m_hFileOP==NULL ){
return RET_FILENOTOPENNED;
}
WaitForSingleObject( m_hFileOP, INFINITE );
//開啟對映檔案
m_hMappingFile = OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, lpszMappingName );
if ( m_hMappingFile==NULL ){
dwRet = RET_FILEERR;
}
else{
//獲得對應的對映地址
m_lpAddress = MapViewOfFile( m_hMappingFile, FILE_MAP_ALL_ACCESS,
0, 0, 0 );
if ( m_lpAddress==NULL ){
dwRet = RET_FILEERR;
}
else{
//獲得對映記憶體頭資訊
if ( m_pusMapInfo==NULL )
m_pusMapInfo = new US_MAPINFO;
memcpy( m_pusMapInfo, m_lpAddress, INFO_LEN );
//儲存地址和遊標
//同建立時候的原理
m_lpAddress = m_lpCursor = (LPVOID)( (LPBYTE)m_lpAddress + INFO_LEN );
//設定開啟標誌資訊
m_isFileLoaded = TRUE;
m_isMyHandle = TRUE;
}
}
ReleaseMutex( m_hFileOP );
return dwRet;
}
//關閉檔案
DWORD UC_FILEMAPPING::Close(BOOL wantDump)
{
//狀態監測
if ( m_isFileLoaded==FALSE )
return RET_FILENOTOPENNED;
DWORD dwRet = RET_OK;
WaitForSingleObject( m_hFileOP, INFINITE );
if ( wantDump )
FlushView();
delete m_pusMapInfo;
m_pusMapInfo = NULL;
m_isFileLoaded = FALSE;
ReleaseMutex( m_hFileOP );
//只有建立者才有權利關閉控制程式碼
if ( m_isMyHandle==FALSE ){
CloseHandle( m_hPhysicsFile );
CloseHandle( m_hMappingFile );
CloseHandle( m_hFileOP );
}
return dwRet;
}
//讀取對映檔案
DWORD UC_FILEMAPPING::Read(LPVOID lpBuf, UINT &nSize, DWORD dwOffsetLow )
{
//狀態監測
if ( m_isFileLoaded==FALSE )
return RET_FILENOTOPENNED;
//引數監測
if ( lpBuf==NULL || nSize==0 )
return RET_BADARG;
DWORD dwRet = RET_OK;
WaitForSingleObject( m_hFileOP, INFINITE );
//計算內容是否溢位
UINT nSizeUsed = (UINT)( LPBYTE(m_lpCursor) - LPBYTE(m_lpAddress) );
if ( nSize
}
else{
//寫入資訊
nSize = nSizeUsed;
memcpy( lpBuf, (LPVOID)( (LPBYTE)m_lpAddress + dwOffsetLow ), nSize );
}
ReleaseMutex( m_hFileOP );
return dwRet;
}
//寫入對映檔案
DWORD UC_FILEMAPPING::Write(LPVOID lpBuf, UINT &nSize, DWORD dwOffsetLow, BOOL isAppend )
{
//狀態監測
if ( m_isFileLoaded==FALSE )
return RET_FILENOTOPENNED;
//引數監測
if ( lpBuf==NULL || nSize==0 )
return RET_BADARG;
DWORD dwRet = RET_OK;
WaitForSingleObject( m_hFileOP, INFINITE );
//計算內容是否溢位
UINT nLeftSize = (UINT)m_pusMapInfo->dwSizeLow - (UINT)( LPBYTE(m_lpCursor) - LPBYTE(m_lpAddress) )
- INFO_LEN;
if ( nLeftSize
}
else{
//根據移動遊標
if ( isAppend==FALSE ){
m_lpCursor = (LPVOID)( (LPBYTE)m_lpAddress + dwOffsetLow );
}
//寫入資訊
memcpy( m_lpCursor, lpBuf, nSize );
//移動遊標
if ( isAppend )
m_lpCursor = (LPVOID)( (LPBYTE)m_lpCursor + nSize );
//記錄檔案使用情況
m_pusMapInfo->dwSizeUsedLow = (DWORD)( (LPBYTE)m_lpCursor - (LPBYTE)m_lpAddress );
}
ReleaseMutex( m_hFileOP );
return dwRet;
}
//獲得錯誤資訊
DWORD UC_FILEMAPPING::GetErrorMessage()
{
DWORD dwRet = GetLastError();
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwRet,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
// Process any inserts in lpMsgBuf.
// ...
// Display the string.
//MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
TRACE( "0x%08X: %sn", dwRet, lpMsgBuf );
// Free the buffer.
LocalFree( lpMsgBuf );
return dwRet;
}
//得到對映檔案大小
DWORD UC_FILEMAPPING::GetSize()
{
if ( m_isFileLoaded==FALSE )
return RET_FILENOTOPENNED;
if ( m_pusMapInfo )
return m_pusMapInfo->dwSizeLow - INFO_LEN;
else
return -1;
}
//得到對映檔案使用大小
DWORD UC_FILEMAPPING::GetSizeUsed()
{
if ( m_isFileLoaded==FALSE )
return RET_FILENOTOPENNED;
if ( m_pusMapInfo )
return m_pusMapInfo->dwSizeUsedLow;
else
return -1;
}
//輸出內容
DWORD UC_FILEMAPPING::FlushView()
{
//狀態監測
if ( m_isFileLoaded ){
if ( m_lpCursor > m_lpAddress && m_hPhysicsFile ){
SIZE_T nSize = (SIZE_T)( (LPBYTE)m_lpCursor - (LPBYTE)m_lpAddress );
if ( FlushViewOfFile( m_lpAddress, nSize ) )
return RET_OK;
else
return RET_FILEERR;
}
return RET_OK;
}
else{
return RET_FILENOTOPENNED;
}
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-996493/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 理不辨不明,寫了一些關於分散式的理解,歡迎各位批評指正分散式
- 簡易撲克牌遊戲簡單實現,歡迎指正遊戲
- 整理thinkphp3.2.3thinkphp5.0thinkphp5.1歡迎補充指正PHP
- 重構wangEditor(web富文字編輯器),歡迎指正!Web
- 如何講授和學習《軟體創新設計》課程,歡迎討論,敬請指正
- SkyHome DEMO//學習Struts等而做的系統,歡迎指正
- EMPI原始碼剖析(原創)原始碼
- [原創] KCP 原始碼分析(上)原始碼
- [原創] KCP 原始碼解析(下)原始碼
- JAVA開原始碼交流QQ群!!歡迎加入並討論!!Java原始碼
- 釋出一個自認為安全的 webbook 自動部署流程 歡迎拍磚指正Web
- 個人的一點理解[為什麼中國公司不歡迎OO?][個人原創]
- CMultiFTP類原始碼 (轉)FTP原始碼
- 億憶網客戶端原始碼開源!歡迎探討!客戶端原始碼
- Linux命令大全 歡迎補充 評論新增~Linux
- 2016美賽A/B題目翻譯及簡單思路(個人觀點,歡迎批評討論)
- NV歡迎Intel進入GPU市場 黃仁勳如此評價IntelGPU
- [原創]非常粗糙的FileFuzz原始碼[0325更新]原始碼
- 從“遊戲批評”到“玩遊戲批評”遊戲
- 指令碼+批處理打造IIS監控器『羅斌原創』薦指令碼
- 北京歡迎AIAI
- 20個最受歡迎的Linux命令(轉)Linux
- 社交交友原始碼app為何受歡迎?它具有哪些功能特點?原始碼APP
- Flume-NG原始碼閱讀之Interceptor(原創)原始碼
- 歪批IT之十七:爸爸式評估(轉)
- Java (原創) (轉)Java
- 盤點五類最受歡迎的開源雲專案
- android 歡迎介面Android
- 歡迎體驗BotBattleBAT
- 有興趣瞭解一下審批工作流歡迎來討論!!!!!
- APENFT基金會獲評“年度最受歡迎NFT專案”獎項
- 2022年1-6月墨天輪最受歡迎的25篇原創技術文章
- mapreduce job提交流程原始碼級分析(二)(原創)原始碼
- Oracle 創始人埃裡森批評亞馬遜是偽君子Oracle亞馬遜
- 【轉】15個最受歡迎的Python開源框架Python框架
- 重新顯示 Windows 98 歡迎對話方塊(轉)Windows
- 中國開源雲聯盟年度評選正式啟動,歡迎申報!
- [原創]介面、類、抽象類、物件的另類解釋抽象物件