FileMapping用户类源代码(原创, 欢迎批评指正)

    技术2022-05-11  115

    欢迎指正

    // uc_filemapping.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 tagMapInfo{

     DWORD  dwSizeHigh;     //高位文件大小 DWORD  dwSizeLow;     //低位文件大小

     DWORD  dwSizeUsedHigh;    //高位使用大小 DWORD  dwSizeUsedLow;    //低位使用大小

     char  szMappingName[_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_hPhysicsFile;    //物理文件句柄 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 _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif

    //// Construction/Destruction//

    //构造函数UC_FILEMAPPING::UC_FILEMAPPING(){ WaitForSingleObject( 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<nSizeUsed ){  dwRet = RET_BUFFEROVERFLOW; } 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<nSize ){  dwRet = RET_BUFFEROVERFLOW; } 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( "0xX: %s/n", 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; }}


    最新回复(0)