#include "MemoryMapReader.h"
#include <windows.h>
#define memfile_block_size 64*1024
//------------------------------------------------------------------------------------
class CMemoryMapReader::Impl
{
unsigned int file_size_;
HANDLE handle_file_;
HANDLE handle_map_;
unsigned int cur_block_size_;
unsigned int cur_block_pos_;
char* cur_block_ptr_;
unsigned int cur_block_offset_;
public:
Impl();
~Impl();
public:
bool Open(const TCHAR* path);
void Close();
bool IsEOF();
unsigned int GetFileSize();
unsigned int GetReaderOffset();
bool SetReaderOffeset(const unsigned int& offset);
unsigned int ReadData(void* data_buf, const unsigned int& read_len);
private:
bool i_OpenFile(const TCHAR* file);
bool i_CreateFileMap();
bool i_MapNextBlock();
void i_CloseFileMap();
void i_CloseFile();
};
//------------------------------------------------------------------------------------
CMemoryMapReader::Impl::Impl()
: handle_file_()
, handle_map_()
, file_size_()
, cur_block_pos_()
, cur_block_ptr_()
, cur_block_size_()
, cur_block_offset_()
{
}
CMemoryMapReader::Impl::~Impl()
{
Close();
}
void CMemoryMapReader::Impl::i_CloseFileMap()
{
if ( cur_block_ptr_ ) ::UnmapViewOfFile(cur_block_ptr_);
if ( handle_map_ && (handle_map_ != INVALID_HANDLE_VALUE) ) ::CloseHandle(handle_map_);
cur_block_ptr_ = 0;
handle_map_ = 0;
}
void CMemoryMapReader::Impl::i_CloseFile()
{
if ( handle_file_ && (handle_file_ != INVALID_HANDLE_VALUE) ) CloseHandle(handle_file_);
handle_file_ = 0;
file_size_ = 0;
cur_block_pos_ = 0;
cur_block_ptr_ = 0;
cur_block_size_ = 0;
cur_block_offset_ = 0;
}
bool CMemoryMapReader::Impl::i_OpenFile(const TCHAR* file)
{
Close();
handle_file_ = ::CreateFile(file, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (handle_file_ == INVALID_HANDLE_VALUE)
{
return false;
}
file_size_ = ::GetFileSize(handle_file_, 0); // max file size : 4G
return i_CreateFileMap();
}
bool CMemoryMapReader::Impl::i_CreateFileMap()
{
do
{
if (file_size_ == 0xFFFFFFFF) break;
handle_map_ = ::CreateFileMapping(handle_file_, 0, PAGE_READWRITE, 0, file_size_, 0);
if (handle_map_ == INVALID_HANDLE_VALUE) break;
cur_block_pos_ = 0;
cur_block_size_ = memfile_block_size;
if ((file_size_-cur_block_pos_) < memfile_block_size)
{
cur_block_size_ = file_size_-cur_block_pos_; // rest data of current block is less than 64K
}
cur_block_ptr_ = (char*)::MapViewOfFile(handle_map_, FILE_MAP_READ|FILE_MAP_WRITE, 0, cur_block_pos_, cur_block_size_);
cur_block_offset_ = 0;
return true;
} while (0);
Close();
return false;
}
bool CMemoryMapReader::Impl::i_MapNextBlock()
{
if (cur_block_ptr_) ::UnmapViewOfFile(cur_block_ptr_);
cur_block_ptr_ = 0;
cur_block_pos_ += cur_block_size_;
if (file_size_ <= cur_block_pos_)
{
return false;//end of file
}
cur_block_size_ = memfile_block_size;
if (file_size_ - cur_block_pos_ < memfile_block_size)
{
cur_block_size_ = file_size_ - cur_block_pos_;
}
cur_block_ptr_ = (char*)::MapViewOfFile(handle_map_, FILE_MAP_READ|FILE_MAP_WRITE, 0, cur_block_pos_, cur_block_size_);
cur_block_offset_ = 0;
return (cur_block_ptr_ != NULL);
}
bool CMemoryMapReader::Impl::Open(const TCHAR* path)
{
if (!path) return false;
bool flag = i_OpenFile( path );
if (false == flag) return false;
return SetReaderOffeset(0);
}
void CMemoryMapReader::Impl::Close()
{
i_CloseFileMap();
i_CloseFile();
}
unsigned int CMemoryMapReader::Impl::GetFileSize()
{
return file_size_;
}
unsigned int CMemoryMapReader::Impl::GetReaderOffset()
{
return (cur_block_pos_ + cur_block_offset_);
}
bool CMemoryMapReader::Impl::IsEOF()
{
return (GetReaderOffset() >= file_size_);
}
bool CMemoryMapReader::Impl::SetReaderOffeset(const unsigned int& offset)
{
if (!handle_map_ || handle_map_==INVALID_HANDLE_VALUE) return false;
if (file_size_ < offset) return false;
unsigned int offTemp = offset;
if (cur_block_ptr_) ::UnmapViewOfFile(cur_block_ptr_);
cur_block_ptr_ = 0;
unsigned int real_set = offTemp;
if (offTemp % memfile_block_size)
{
offTemp = memfile_block_size * (offTemp/memfile_block_size);
}
real_set -= offTemp; // real_set == offset of one block
cur_block_pos_ = offTemp;
cur_block_size_ = memfile_block_size;
if (file_size_ - cur_block_pos_ < memfile_block_size)
{
cur_block_size_ = file_size_ - cur_block_pos_; // rest data of current block is less than 64K
}
cur_block_ptr_ = (char*)::MapViewOfFile(handle_map_, FILE_MAP_READ|FILE_MAP_WRITE, 0, cur_block_pos_, cur_block_size_);
cur_block_offset_ = real_set;
return (cur_block_ptr_ != NULL);
}
unsigned int CMemoryMapReader::Impl::ReadData(void* data_buf, const unsigned int& read_len)
{
if (!cur_block_ptr_ || !data_buf) return 0;
char* dst_buf = (char*)data_buf;
unsigned int len = read_len;
unsigned int rest_data; // rest len of current block
while (len > 0)
{
rest_data = cur_block_size_ - cur_block_offset_;
if (rest_data > len) rest_data = len;
memcpy(dst_buf, cur_block_ptr_+cur_block_offset_, rest_data);
cur_block_offset_ += rest_data;
dst_buf += rest_data;
len -= rest_data;
if (cur_block_size_ == cur_block_offset_)
{
if (false == i_MapNextBlock())
{
break;
}
}
}
return read_len - len;
}
//===================================================================================================
CMemoryMapReader::CMemoryMapReader()
{
self = new Impl();
}
CMemoryMapReader::~CMemoryMapReader()
{
delete self;
}
bool CMemoryMapReader::Open(const TCHAR* path)
{
return self->Open(path);
}
void CMemoryMapReader::Close()
{
self->Close();
}
unsigned int CMemoryMapReader::GetFileSize()
{
return self->GetFileSize();
}
unsigned int CMemoryMapReader::GetReaderOffset()
{
return self->GetReaderOffset();
}
bool CMemoryMapReader::SetReaderOffeset(const unsigned int& offset)
{
return self->SetReaderOffeset(offset);
}
bool CMemoryMapReader::IsEOF()
{
return self->IsEOF();
}
unsigned int CMemoryMapReader::ReadData(void* data_buf, const unsigned int& read_len)
{
return self->ReadData(data_buf, read_len);
}
内存映射的封装 包含读、写文件
5星 · 超过95%的资源 需积分: 49 107 浏览量
2015-11-27
11:25:47
上传
评论 7
收藏 5KB ZIP 举报
月光海岸
- 粉丝: 1
- 资源: 30
最新资源
- Win64OpenSSL-3-3-0.exe
- 课高分程设计-基于C++实现的民航飞行与地图简易管理系统-南京航空航天大学
- 航天器遥测数据故障检测系统python源码+文档说明+数据库(课程设计)
- 北京航空航天大学操作系统课设+ppt+实验报告
- 基于Vue+Echarts实现风力发电机中传感器的数据展示监控可视化系统+源代码+文档说明(高分课程设计)
- 基于单片机的风力发电机转速控制源码
- 基于C++实现的风力发电气动平衡监测系统+源代码+测量数据(高分课程设计)
- 毕业设计- 基于STM32F103C8T6 单片机,物联网技术的太阳能发电装置+源代码+文档说明+架构图+界面截图
- 基于 LSTM(长短期记忆)(即改进的循环神经网络)预测风力发电厂中风力涡轮机产生的功率+源代码+文档说明
- 基于stm32f103+空心杯电机+oled按键+运动算法
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
前往页