下面是我在编程中运用CTypedPtrMap指针模板类的方法,其存储结构占用物理空间小,比单纯的用数组结构存储的文件将小很多,所以是一种非常推荐的存储及读取文件的方法。
你必须在stdafx.h文件中 包含 #include <afxtempl.h> // MFC templates
在头文件中包含 #include <io.h>
其中 CBank.h文件如下:
class CBank : public CObject
{
DECLARE_SERIAL(CBank) //声明序列化存储
public:
CBank();
CBank(CString str){ m_bankname = str; }
CBank(const CBank &b){ m_bankname= b.m_bankname;} //拷贝构造函数
virtual ~CBank();
private:
CString m_bankname;
public:
virtual void Serialize(CArchive& ar);
};typedef CTypedPtrMap<CMapStringToOb,
CString,
CBank*>CBanktmp; //这个才是我们根据此类生成的类型
它的实现文件.cpp如下:
IMPLEMENT_SERIAL(CBank, CObject, 1) //实现序列化存储
CBank::CBank()
{
m_bankname="";
}
CBank::~CBank()
{}
void CBank::Serialize(CArchive& ar)
{
if (ar.IsLoading())
{
ar >> m_bankname;
}
else
{
ar << m_bankname;
}
}
/*----------------------------------------------------
从文件中读取参数:
注意: 其中的m_map是这样定义的:CBanktmp m_map;
-------------------------------------------------*/
void CDlgBankIn::LoadBankName()
{
UINT nFlags = CFile::typeBinary |CFile::modeReadWrite;
if(_access(_T("BankName.dat"),0))
{
nFlags |= CFile::modeCreate;
}
CFile file;
CFileException fe;
if (file.Open(_T("BankName.dat"),nFlags, &fe))
{
if(file.GetLength()==0) //如果文件为空则不进行读取操作
{
}
else
{
CArchive ar(&file, CArchive::load);
m_map.Serialize(ar); //读取文件
//根据文件内容填充列表框
POSITION pos;
CString strKey;
CBank *pB=NULL;
for( pos = m_map.GetStartPosition(); pos != NULL; )
{
m_map.GetNextAssoc(pos,strKey,(CBank*)pB);
m_CmbBank.AddString(strKey);
}
delete pB;
}
}
file.Close();
}
/*-------------------------------------------------
功能: 先打开文件,然后查找文件中是否有与编辑框关键字相同的内容,
如果有相同内容则不添加,如果没有相同内容则写文件.
------------------------------------- ------------*/
void CDlgBankList::OnBtnAdd()
{
// TODO: Add your control notification handler code here
CString strKey;
GetDlgItemText(IDC_EDITBank,strKey);
if (0 != strKey.GetLength())
{
CBank *pB;
//打开文件
UINT nFlags = CFile::typeBinary |CFile::modeRead;
CFile file;
CFileException fe;
if (file.Open(_T("BankName.dat"),nFlags, &fe))
{
if(file.GetLength()==0) //如果文件为空则不进行序列化操作
{ }
else
{
CArchive ar(&file, CArchive::load);
m_map.Serialize(ar);
}
//分析文件并给文件添加编辑框的内容
if(!m_map.Lookup(strKey,(CBank*)pB)) //当不存在时才需要添加
{
if (CB_ERR != m_ListBox.AddString(strKey))
{
m_map.SetAt(strKey, new CBank(strKey)); //给关键字strKey赋值
}
}
}
file.Close();
//存储文件
nFlags = CFile::typeBinary |CFile::modeWrite;
if (file.Open(_T("BankName.dat"),nFlags, &fe))
{
CArchive ar(&file, CArchive::store);
m_map.Serialize(ar); //序列化存储
}
}
}
/*-------------------------------------------------
功能: 先打开文件,然后查找文件中的关键字,
找到后则删除此关键字, 但是注意关键字对应的内容仍然没有删除,这点期待改进.
-------------------------------------------------*/
void CDlgBankList::OnBtnDel()
{
// TODO: Add your control notification handler code here
int iIndex;
CString strKey;
if(LB_ERR!=m_ListBox.GetCurSel())
{
//打开文件
& nbsp; UINT nFlags = CFile::typeBinary |CFile::modeRead;
CFile file;
CFileException fe;
if (file.Open(_T("BankName.dat"),nFlags, &fe))
{
CArchive ar(&file, CArchive::load);
m_map.Serialize(ar);
iIndex=m_ListBox.GetCurSel();
m_ListBox.GetText(iIndex,strKey);
m_ListBox.DeleteString(iIndex);
//分析文件并给文件添加编辑框的内容
CBank *pB=NULL;
if(m_map.Lookup(strKey,(CBank*)pB))
{
m_map.RemoveKey(strKey); //删除关键字,但没有删除关键字对应的内容
}
}
file.Close();
//存储文件
nFlags = CFile::typeBinary |CFile::modeWrite;
if (file.Open(_T("BankName.dat"),nFlags, &fe))
{
CArchive ar(&file, CArchive::store);
m_map.Serialize(ar); //序列化存储
}
}
}