用sdk做的软件,想保存一些程序数据,设置。不用 ini 或 xml,用API的ReadFile和WriteFile。需要:
⒈ 直接读取相应的设置,比如:通过"Version"读取1.0.0.1;通过AutoRun读取1。
⒉ 读取提醒,并可删除,排序。
⒊ 效率高(内存映射文件是否比直接读取要快呢?)。如果有用 STL 完成的类也行。请给个现成的类好吗?拜托了!另100:http://community.csdn.net/Expert/topic/5460/5460930.xml?temp=.4094507邮件:[email protected]
⒈ 直接读取相应的设置,比如:通过"Version"读取1.0.0.1;通过AutoRun读取1。
⒉ 读取提醒,并可删除,排序。
⒊ 效率高(内存映射文件是否比直接读取要快呢?)。如果有用 STL 完成的类也行。请给个现成的类好吗?拜托了!另100:http://community.csdn.net/Expert/topic/5460/5460930.xml?temp=.4094507邮件:[email protected]
然后用boost::Serialization将map序列化到内存中
用的时候 还用 boost::Serialization将map还原
这是最方便的办法
#pragma once#include<list>
using namespace std;
/********************宏定义**********************************/
#define RD_FILE_FLAGE 0x20070412 //记录文件标志
#define RD_FILE_OK 0 //纪录文件操作成功
#define FILE_NO_EXISI -1 //纪录文件不存在
#define FILE_FLAG_ERROR -2 //文件标志错
#define FILE_HEAD_ERROR -3 //文件头出错
#define FILE_CONTENT_ERROR -4 //文件内容出错
#define FILE_SAVE_ERROR -5 //保存文件出错
#define RD_NO_EXISI -6 //纪录不存在
#define RD_RE_EXISI -7 //纪录已存在struct SRdFileHeader; //纪录文件头声明 /********************记录文件的操作模块定义*****************/
//注意:一定要重载纪录的==操作符,使得相等即主键相等
template<class RdType>
class CRdFile:public std::list<RdType>
{public: int Open(std::string FileName); //打开记录文件,并加载文件内容到list
int Inquiry(RdType&); //查询,返回指定主键相应的记录信息
int Add( const RdType& ); //添加一条记录信息
int Updata( const RdType& ); //修改一条指定的记录信息
int Delete( const RdType& ); //删除一条指定的纪录
int Close(); //关闭,将保存list到文件,覆盖原文。若没有,创建新的
CRdFile(void);
~CRdFile(void);
private:
std::string m_FileName; //纪录文件名
};
/********************记录文件头定义************************/
struct SRdFileHeader
{
unsigned int wRdFileFlag; //记录文件标志
unsigned int wRdCount; //记录条数
unsigned int wRdSize; //单位记录长度};
/***********************************************************/
template<class RdType>
CRdFile<RdType>::CRdFile(void)
{}
template<class RdType>
CRdFile<RdType>::~CRdFile(void)
{}
/****************************************************************
说明:打开指定的记录文件,加载文件中的纪录到m_RdList,
并且保存文件名到m_FileName,以便保存
输入:FileName 记录文件的名称
输出:成功返回0,否则返回定义的错误代码
****************************************************************/
template<class RdType>
int CRdFile<RdType>::Open(std::string FileName)
{
SRdFileHeader m_FileHead;
m_FileName=FileName;
FILE *fp=fopen(m_FileName.c_str(),"r");//打开文件
if(fp==NULL)
{
//printf("fp==NULL\n");
return FILE_NO_EXISI;
}
int iRead; iRead=(int)fread(&m_FileHead,sizeof(m_FileHead),1,fp);//取文件头部 if(iRead!=1)
{
//printf("iRead!=sizeof(m_FileHead)\n");
fclose(fp);
return FILE_HEAD_ERROR;
}
char *pBuf=new char[m_FileHead.wRdCount*m_FileHead.wRdSize]; iRead=(int)fread(pBuf,m_FileHead.wRdSize,m_FileHead.wRdCount,fp);//取所有的纪录 if(iRead!=m_FileHead.wRdCount)
{
//printf("iRead!=m_FileHead.wRdCount*m_FileHead.wRdSize\n");
delete[] pBuf;
return FILE_CONTENT_ERROR;
fclose(fp);
} clear();
char* p=pBuf;
for(unsigned int i=0;i<m_FileHead.wRdCount;i++,p+=m_FileHead.wRdSize)
{
push_back(*(RdType*)p); //将所有的纪录保存的m_RdList
} fclose(fp);
delete[] pBuf;
return 0;}/****************************************************************说明:根据指定主键得纪录,获得该纪录的信息
输入:Rd 纪录中指定主键
输出:成功返回0,否则返回定义的错误代码
并且,查询成功时,Rd返回纪录的信息****************************************************************/
template<class RdType>
int CRdFile<RdType>::Inquiry(RdType& Rd)
{
iterator pList=begin();
for(; pList!=end(); pList++)
{
if((*pList)==Rd)
{
Rd=(*pList);
//printf("Add failed \n");
return 0; }
}
//printf("Add ok\n");
//m_RdList.push_back(Rd);
return RD_NO_EXISI;
}/****************************************************************说明:添加一条纪录信息
输入:Rd 新添的纪录信息
输出:成功返回0,否则返回定义的错误代码(主键重复)****************************************************************/
template<class RdType>
int CRdFile<RdType>::Add(const RdType& Rd)
{ iterator pList=begin();
for(; pList!=end(); pList++)
{
if((*pList)==Rd)
{
//printf("Add failed \n");
return RD_RE_EXISI; }
}
//printf("Add ok\n");
push_back(Rd);
return 0;}/****************************************************************说明:更新一条纪录信息,根据主键更新已经存在的记录信息
输入:Rd 更新的纪录信息
输出:成功返回0,否则返回定义的错误代码(主键不存在)****************************************************************/
template<class RdType>
int CRdFile<RdType>::Updata(const RdType& Rd)
{ iterator pList=begin();
for(;pList!=end();pList++)
{ if((*pList)==Rd)
{
*pList=Rd;
return 0;
}
} return RD_NO_EXISI;}/****************************************************************说明:删除一条纪录信息,根据主键删除已经存在的记录信息
输入:Rd 指定将要删除的纪录主键
输出:成功返回0****************************************************************/
template<class RdType>
int CRdFile<RdType>::Delete(const RdType& Rd)
{
remove(Rd);
return 0;
}/****************************************************************说明:关闭记录文件,保存m_RdList中的纪录到文件,
m_FileName指定文件名,若文件已经存在,则覆盖原文
否则,新创建文件
输出:成功返回0,否则返回定义的错误代码****************************************************************/
template<class RdType>
int CRdFile<RdType>::Close()
{
SRdFileHeader m_FileHead;
m_FileHead.wRdFileFlag=0;
m_FileHead.wRdCount=size();
m_FileHead.wRdSize=sizeof(RdType);
FILE *fp=fopen(m_FileName.c_str(),"w+");
if(fp==NULL) return -1; fwrite(&m_FileHead,sizeof(m_FileHead),1,fp); RdType TempRd;
iterator pList=begin();
for(;pList!=end();pList++)
{
TempRd=*pList;
fwrite(&TempRd,sizeof(RdType),1,fp);
}
fclose(fp);
return 0;
}
因为即使是取一条信息,也要将所有记录读取到List中。我现在需要:信息类型多样,比如,配置信息,歌曲目录,提醒信息,通讯录,都放在一个文件里。而且,我想取其中一条信息时,并不想将所有文件都读入内存(这样内存占用比较大),而只想将自己需要的信息读取到内存中。而且,想要效率高些。因为在Windows下编程,希望使用:ReadFile/WriteFile组合的文件读写类。
⒈ 直接读取相应的设置,比如:通过"Version"读取1.0.0.1;通过AutoRun读取1。
⒉ 读取提醒,并可删除,排序。
⒊ 效率高(内存映射文件是否比直接读取要快呢?)。
---------------------------------------------------------------------------------
答:
1、2 这个dat文件格式规范一下,比如:每条记录占用定长50个字节,头10个字节存放Version,不足长度的话补0,后面1个字节存入AutoRun,依此类推,就可以按文件的位置访问指定内容了。不过,不明白楼主为何不用数据库存储,数据库天生就是为你这样的访问方法发明的。
3 内存映射文件是比直接读取效率要高多了。不过如果文件存放没什么规律的话,那就派不上用场了。
乖乖
所以准备用内存映射文件实现data读写。
比如:
1-10K:核心设置
11-100K:提醒内容
101-200K:通讯录
这样,我如果增加或删除,则只需要对相应范围内的数据进行操作即可。
我要做一个常驻托盘的程序,所以对CPU、内存的占用非常在意。哪怕是4个字节...
我希望将内存控制在500K以下。