该实例是在程序的exe路径下,实现读取,写入内存映射文件功能
头文件
#ifdef GERNERAL_PRODUCTDATA_EXP
#define GERNERAL_PRODUCTDATA_API _declspec(dllexport)
#else
#define GERNERAL_PRODUCTDATA_API _declspec(dllimport)
#endif // GERNERAL_PRODUCTDATA_EXP
class GERNERAL_PRODUCTDATA_API TestDataFile
{
public:
TestDataFile();
~TestDataFile();
public:
//读取内存映射文件
static bool ReadMapFile();
//获取文件中数据
static SaveTestDataStruct* GetMapFileData();
//保存内存映射文件
static bool SaveMapFile();
//关闭内存映射文件
static bool CloseMapFile();
private:
static bool m_bIsOpen;//是否已经打开内存映射文件
static HANDLE m_hFile;//文件句柄
static HANDLE m_hMapFile;//内存映射文件句柄
static LPVOID m_pFileVal;//存储值的指针
};
#endif
源文件
#include "stdafx.h"
#include "TestDataFile.h"
/*-------------全局变量----------------*/
bool TestDataFile::m_bIsOpen = false;
HANDLE TestDataFile::m_hFile=NULL;
HANDLE TestDataFile::m_hMapFile=NULL;
a
LPVOID TestDataFile::m_pFileVal=NULL;
TestData2File::TestDataFile()
{
}
TestData2File::~TestDataFile()
{
}
//得到可执行文件的路径
CString GetExePath(void)
{
CString strExePath;
GetModuleFileName(NULL, strExePath.GetBuffer(MAX_PATH), MAX_PATH);
strExePath.ReleaseBuffer();
strExePath = strExePath.Left(strExePath.ReverseFind(_T('\\')));
return strExePath;
}
bool TestDataFile::ReadMapFile()
{
if (m_bIsOpen)//如果已经读过就不再读
{
return true;
}
//文件名字
CString filename1 = GetExePath() + _T("\\MemMap.data");
m_hFile = CreateFile(
filename1,
GENERIC_WRITE | GENERIC_READ, // 写和读文件。
FILE_SHARE_READ | FILE_SHARE_WRITE, // 不共享读写。
NULL, // 缺省安全属性。
OPEN_ALWAYS, // 如果文件存在,打开文件。如果文件不存在,则创建文件
FILE_ATTRIBUTE_NORMAL, // 一般的文件。
NULL);
if (m_hFile == INVALID_HANDLE_VALUE)
{
return false;
}
m_hMapFile = CreateFileMapping(
m_hFile, // 如果这值为INVALID_HANDLE_VALUE,是合法的,上步一定测试啊
NULL, // 默认安全性
PAGE_READWRITE, // 可读写
0, // 2个32位数示1个64位数,最大文件字节数,
// 高字节,文件大小小于4G时,高字节永远为0
sizeof(SaveTestDataStruct),//dwFileSize, // 此为低字节,也就是最主要的参数,如果为0,取文件真实大小
NULL);
if (m_hMapFile == NULL)
{
CloseHandle(m_hFile); // 关闭文件
return false;
}
int xlsize = sizeof(SaveTestDataStruct);
// 步骤3:将文件数据映射到进程的地址空间
m_pFileVal = MapViewOfFile( //pvFile就是得到的指针,用它来直接操作文件
m_hMapFile,
FILE_MAP_WRITE, // 可写
0, // 文件指针头位置 高字节
0, // 文件指针头位置 低字节 必为分配粒度的整倍数,windows的粒度为64K
sizeof(SaveTestDataStruct)); // 要映射的文件尾,如果为0,则从指针头到真实文件尾
if (m_pFileVal == NULL)
{
CloseHandle(m_hMapFile);
CloseHandle(m_hFile);
return false;
}
m_bIsOpen = true;
return m_bIsOpen;
}
SaveTestDataStruct* TestDataFile::GetMapFileData()
{
if (!m_bIsOpen)
{
return NULL;
}
return (SaveTestDataStruct*)m_pFileVal;
}
bool TestDataFile::SaveMapFile()
{
if (!m_bIsOpen)
{
return false;
}
//将内存保存在文件中
FlushViewOfFile(m_pFileVal, sizeof(SaveTestDataStruct));
return true;
}
bool TestDataFile::CloseMapFile()
{
if (!m_bIsOpen)
{
return false;
}
m_bIsOpen = false;
UnmapViewOfFile(m_pFileVal); // 释放内存映射文件的头指针
CloseHandle(m_hMapFile); // 内存映射文件句柄
CloseHandle(m_hFile); // 关闭文件
return true;
}
自定义一个数据结构
//保存测试结果的结构体
typedef struct tagSaveTestDataStruct
{
CapCarrier AllCapCarrier[TOTAL_CAR_NUM];
CapCarrier TestOutCarrier[TEST_OUTCAR_NUM];
..//还有很多类型,这里不一一列举
int nEsrRecpNo;
bool bCanFeed;
}SaveTestDataStruct;
使用该类来读取文件
/读取内存映射文件
void VisionMotionInterface::ReadMemMapFile()
{
//读取内存映射文件
if (!TestDataFile::ReadMapFile())
{
HMIMsgBoxCenter(__FUNCTION__ +_T("中ReadMapFile失败!"), HMI_MSG_OK);
return;
}
//获取结果
SaveTestDataStruct* tempData = TestDataFile::GetMapFileData();
//进料模块
for (int i=0;i< FEED_CAP_NUM;i++)
{
m_CapFeedMotion.tCapFeedMove.FeedCaryTestData[i] = tempData->FeedInResult[i];//进料数据
}
}
使用该类来写入文件
//获取结果
void VisionMotionInterface::SaveMemMapFile()
{
SaveTestDataStruct* tempData = TestData2File::GetMapFileData();
//开短路仪表的配方参数
tempData->nOSRecpNo=m_CapFeedMotion.tCapFeedMove.nOSMeterRecipeNo;
//ESR仪表的配方参数
tempData->nEsrRecpNo=m_CapFeedMotion.tCapFeedMove.nESRMeterRecipeNo;
//是否可以进料
tempData->bCanFeed =m_CapFeedMotion.tCapFeedMove.bCanFeed;
TestData2File::SaveMapFile();
TestData2File::CloseMapFile();
m_runlog.addRunLog(_T("保存内存映射文件成功!"));
}