仙人指路的编程乐园
留言簿 主人介绍 返回主页
Windows驱动 毕设 电子电路 电脑 PE外壳 心情 Windows应用程序 随笔 Web技术 加密算法 古老的DOS编程 杂项
一个使用内存映射方式读写文件的类
类别: Windows应用程序  上传时间: 2010-1-5 9:31:59  浏览(264)  留言(0) 
//头文件

#define FILEMAP_MAP_SIZE  (64 * 1024 * 1024)  //每次映射64M
#define FILEMAP_STEP_SIZE  (32 * 1024 * 1024)  //读大数据的时候每次前移32M

class CFileMap 
{
  HANDLE  m_hFile;
  HANDLE  m_hMap;
  int      m_Size;        //文件长度,以字节计
  BYTE*    m_Buf;          //文件的内存映射区
  int      m_FilePosAlign; //映射的文件偏移
  bool    m_ReadOnly; 
public:
  CFileMap();
  ~CFileMap();
  bool ReadOpen(const char* fname);
  bool WriteOpen(const char* fname, int size, bool is_hidden = false, bool is_sysyem = false);
  void Close();
  BYTE* GetBuf(int pos);
  int GetSize()
  {
    return m_Size;
  }
};

//代码文件

CFileMap::CFileMap()
{
  m_FilePosAlign = 0;
  m_hFile = 0;
  m_hMap = 0;
  m_Size = 0;
  m_Buf = 0;
}

//析构函数,关闭内存映射
CFileMap::~CFileMap()
{
  Close();
}

//只读
bool CFileMap::ReadOpen(const char* fname)
{
  m_ReadOnly = true;
  m_hFile = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if(m_hFile == INVALID_HANDLE_VALUE)
  {
    m_hFile = 0;
    return false;
  }
  m_Size = GetFileSize(m_hFile, 0);
  if(m_Size == INVALID_FILE_SIZE)
  { 
    CloseHandle(m_hFile);
    m_Size = 0;
    m_hFile = 0;
    return false;
  }
  m_hMap = CreateFileMapping(m_hFile, 0, PAGE_READONLY, 0, 0, 0);
  if(m_hMap == 0)
  {
    CloseHandle(m_hFile);
    m_Size = 0;
    m_hFile = 0;
    return false;
  }
  return true;
}

//只写
bool CFileMap::WriteOpen(const char* fname, int size, bool is_hidden, bool is_sysyem)
{
  m_ReadOnly = false;
  DWORD attr = FILE_ATTRIBUTE_NORMAL;
  if(is_hidden)
    attr |= FILE_ATTRIBUTE_HIDDEN;
  if(is_sysyem)
    attr |= FILE_ATTRIBUTE_SYSTEM;
  m_hFile = CreateFile(fname, GENERIC_READ|GENERIC_WRITE, 0, 0, CREATE_ALWAYS, attr, 0);
  if(m_hFile == INVALID_HANDLE_VALUE)
  {
    m_hFile = 0;
    return false;
  }
  m_hMap = CreateFileMapping(m_hFile, 0, PAGE_READWRITE, 0, size, 0);
  if(m_hMap == 0)
  {
    CloseHandle(m_hFile);
    m_hFile = 0;
    return false;
  }
  m_Size = size;
  return true;
}

//关闭文件映射
void CFileMap::Close()
{
  if(m_Buf != 0)
    UnmapViewOfFile(m_Buf);
  if(m_hMap != 0)
    CloseHandle(m_hMap);
  if(m_hFile != 0)
    CloseHandle(m_hFile);

  m_hFile = 0;
  m_hMap = 0;
  m_Size = 0;
  m_Buf = 0;
  m_FilePosAlign = 0;
}

//获得文件的内存区映射地址
BYTE* CFileMap::GetBuf(int pos)
{
  if(pos > m_Size)
    return 0;

  BYTE* addr;      //返回的内存地地址
  int  map_size;  //每次映射多长
  DWORD access;

  if(m_Buf != 0) //已经映射了
  {
    UnmapViewOfFile(m_Buf);
    m_Buf = 0;
  }

  m_FilePosAlign = pos / FILEMAP_STEP_SIZE * FILEMAP_STEP_SIZE;

  if((m_FilePosAlign + FILEMAP_MAP_SIZE) > m_Size)
    map_size = m_Size - m_FilePosAlign;
  else
    map_size = FILEMAP_MAP_SIZE;

  if(m_ReadOnly)
    access = FILE_MAP_READ;
  else
    access = FILE_MAP_ALL_ACCESS;

  m_Buf = (BYTE*)MapViewOfFile(m_hMap, access, 0, m_FilePosAlign, map_size);

  if(m_Buf == 0)
  {
    m_FilePosAlign = 0;
    return 0;
  }
  else
  {
    addr = m_Buf + (pos - m_FilePosAlign);
    return addr;
  }
}
上一篇: MapInfo/MapX求最短路径(3)  下一篇: Java用awt和swing写的两个小窗口程序


留言
 
查看全部留言



Copyright © 2009 BY MISSSIR,网站版权所有。 京ICP备09095257号

花褪残红青青杏小。燕子飞时,绿水人家绕。枝上柳绵吹又少。天涯何处无芳草。
墙里秋千墙外道。墙外行人,墙里佳人笑。笑渐不闻声渐悄。多情总被无情恼。

今年访问量 24089  今月访问量 649  今日访问量 52 

关于 您的地址
您的大名 您的邮箱
QQ/MSN/Tel 是否保密
留言内容