Chinaunix首页 | 论坛 | 博客
  • 博客访问: 358091
  • 博文数量: 78
  • 博客积分: 3380
  • 博客等级: 中校
  • 技术积分: 857
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-16 19:39
文章分类

全部博文(78)

文章存档

2011年(31)

2010年(47)

分类: LINUX

2011-08-17 13:26:14

//定义了fseek定位大于2G内存映射的文件处理有关的Windows平台的接口
//作者:刘成彬
//适合平台:WindowsXP, WindowsCE
#ifndef _MFILE_H
#define _MFILE_H
#include
typedef unsigned long U32;
class CMFile
{
public:
 CMFile();
 virtual ~CMFile();
 BOOL Open(const char* pszFileName);
 BOOL Create(const char* pszFileName, __int64 FileSize);
 void Close();
 __int64 Read(void* lpBuf, DWORD nLength);
 __int64 Write(void* lpBuf, DWORD nLength);
 __int64 ReadFile(__int64 nPos, void* lpBuf , DWORD nLength);
 __int64 WriteFile(__int64 nPos, void* lpBuf , DWORD nLength);
 
 BOOL SetCursorTo(__int64 nPos);
 __int64 GetFileLength();
 __int64 GetFilePos();  
 
private: 
 HANDLE m_hFile;   // 文件句柄
 HANDLE m_hMapping;   // 映射句柄
 PBYTE m_pbFile;   // 映射内存指针
 PBYTE m_pbMapping;   // 映射内存指针
 __int64 m_nFileSize;   // 文件大小
 __int64 m_nFilePointer;   // 文件当前指针
 DWORD m_nSysGranularity;  // 系统粒度
 BOOL m_bOpened;   // 文件打开标志 
private: 
 DWORD MapView(DWORD ViewSize); 
};
#endif
===========================================================

#include "MFile.h"
#include
#define  MAX_PATH 260
CMFile::CMFile()
{
 SYSTEM_INFO si;
 GetSystemInfo( &si );   
 m_nSysGranularity = si.dwAllocationGranularity;
 m_hFile           = NULL;
 m_hMapping        = NULL;
 m_pbFile          = NULL;
 m_nFilePointer    = NULL;
 m_bOpened    = FALSE;
 m_nFileSize       = 0;
}
CMFile::~CMFile()
{
 Close();
}
BOOL CMFile::Open(const char* pszFileName)
{
 assert(pszFileName);
 
 if(m_bOpened)
  Close();
 m_hFile = CreateFile(pszFileName, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
 
 if(INVALID_HANDLE_VALUE == m_hFile) return FALSE;
 
 DWORD dwFileSizeHigh;
 m_nFileSize = GetFileSize(m_hFile, &dwFileSizeHigh);
 m_nFileSize += (((__int64) dwFileSizeHigh) << 32);
 
 m_hMapping = CreateFileMapping( m_hFile, NULL, PAGE_READWRITE,(DWORD)(m_nFileSize >> 32), (DWORD)m_nFileSize, NULL );
 if (m_hMapping ==NULL)
  return FALSE;
 m_bOpened = TRUE;
 
 return TRUE;
}
BOOL CMFile::Create(const char* pszFileName, __int64 FileSize)
{
 assert(pszFileName);
 
 if(FileSize < 0) return FALSE;
 
 if(m_bOpened)
  Close();
 
 m_nFileSize = FileSize;
 
 m_hFile = CreateFile( pszFileName, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ,
  NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
 
 if(INVALID_HANDLE_VALUE == m_hFile) return FALSE;
 
 if(NULL != m_hMapping) UnmapViewOfFile(m_hMapping);
 
 m_hMapping = CreateFileMapping( m_hFile, NULL, PAGE_READWRITE,
  (DWORD)(m_nFileSize >> 32), (DWORD)m_nFileSize, NULL );
 
 if(NULL == m_hMapping) return FALSE;
 
 m_bOpened = TRUE;
 
 return TRUE;
}
void CMFile::Close()
{
 if(UnmapViewOfFile(m_pbMapping)) m_pbMapping = NULL;
 if(CloseHandle(m_hMapping))   m_hMapping  = NULL;
 if(CloseHandle(m_hFile))   m_hFile     = NULL;
 m_nFileSize       = 0;
 m_bOpened         = FALSE;
 m_pbFile          = NULL;
 m_nFilePointer    = NULL;
 m_bOpened    = FALSE;
}
__int64 CMFile::Read(void* lpBuf, DWORD nLength)
{
 assert(lpBuf);
 if(nLength <= 0) return 0;
 DWORD MapSize = MapView(nLength);
 if(MapSize <= 0) return 0;
 memcpy(lpBuf, m_pbFile, MapSize);
 SetCursorTo(m_nFilePointer + MapSize);
 return MapSize;
}
__int64 CMFile::Write(void* lpBuf, DWORD nLength)
{
 assert(lpBuf);
 if(nLength <= 0) return 0;
 if(m_nFilePointer >= m_nFileSize) return 0;
 DWORD MapSize = MapView(nLength);
 if(MapSize <= 0) return 0;
 memcpy(m_pbFile, lpBuf, MapSize);
 SetCursorTo(m_nFilePointer + MapSize);
 return MapSize;
}
__int64 CMFile::ReadFile(__int64 nPos, void* lpBuf , DWORD nLength)
{
 assert(lpBuf && nLength>0);
 if(SetCursorTo( nPos))
        return Read(lpBuf , nLength );
    else
        return 0;
}
__int64 CMFile::WriteFile(__int64 nPos, void* lpBuf , DWORD nLength)
{
 assert(lpBuf && nLength>0);
 if(SetCursorTo( nPos))
        return Write(lpBuf , nLength );
    else
        return 0;
}
BOOL CMFile::SetCursorTo(__int64 nPos)
{
 if(nPos >= m_nFileSize)
 {
  m_nFilePointer = m_nFileSize;
  return FALSE;
 }
 
 if(nPos <= 0)
 {
  m_nFilePointer = 0;
  return FALSE;
 }
 
 m_nFilePointer = nPos;
 return TRUE;
}
__int64 CMFile::GetFileLength()
{
 return m_nFileSize;
}
__int64 CMFile::GetFilePos()
{
 return m_nFilePointer;
}
/** 函数功能:
 根据当前文件指针位置(m_nFilePointer), 和用户要映射的字节数(ViewSize)
 将文件映射到内存.同时置m_pbFile的值, 并且返回用户可读写的字节数;
 1 根据文件指针位置(m_nFilePointer)计算出最接近系统粒度的整数倍的值
   这个值将做为映射的基址
 2 映射的字节数, 这个值加上映射基址不能超出文件的总长度
*/
DWORD CMFile::MapView(DWORD ViewSize)
{
 assert(m_bOpened);
 // 根据当前的文件指针计(m_nFilePointer), 算实际映射位置,
 // 这个值必须是系统粒度的整数倍
 __int64 nRealPos = (m_nFilePointer / m_nSysGranularity) * m_nSysGranularity;
 if(nRealPos >= m_nFileSize) return 0;
 // 计算实际应该映射的字节长度
 __int64 nRealMapLen = ViewSize + (m_nFilePointer - nRealPos);
 if(nRealMapLen > m_nFileSize - nRealPos)
  nRealMapLen = m_nFileSize - nRealPos;
 // 卸载先前映射
 if(NULL != m_pbMapping)
  UnmapViewOfFile(m_pbMapping);
 // 本次映射
 m_pbMapping = (PBYTE)MapViewOfFile( m_hMapping, FILE_MAP_WRITE, (DWORD)(nRealPos >> 32), (DWORD)nRealPos, (DWORD)nRealMapLen);
 // 判断
 if(NULL == m_pbMapping) return 0;
 // 将m_pbFile指针位置置为当前文件指针处
 m_pbFile = m_pbMapping + (m_nFilePointer - nRealPos);
 // 返回m_pbFile指针的可读写字节数
 return (DWORD) (nRealMapLen -  (m_nFilePointer - nRealPos));
}
阅读(2632) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~