MFC中数据文件的存储和加载
1. 传统的数据存储,将数据定义到一个结构体中,用CFile的方式循环读写数据结构体
struct SData { UINT nNumb; TCHAR sName[20]; COleDateTime date; }; void CfffDlg::OnBnClickedSave() { //另存为对话框 CFileDialog fd(FALSE, _T("*.fff"), _T("example"), OFN_OVERWRITEPROMPT, _T("信息文件(*.fff)|*.fff|所有文件|*.*||"), NULL); if (IDCANCEL == fd.DoModal()) return; CFile file; if (!file.Open(fd.GetPathName(), CFile::modeCreate | CFile::modeWrite)) { MessageBox(_T("保存文件出错!"), _T("Tip")); return; } SData s; for (int i = 0; i < m_list.GetItemCount(); ++i) { s.nNumb = _ttoi(m_list.GetItemText(i,0)); m_list.GetItemText(i, 1, s.sName, sizeof(s.sName) / sizeof(s.sName[0])); s.date.ParseDateTime(m_list.GetItemText(i, 2)); file.Write(&s, sizeof(s)); } } void CfffDlg::OnBnClickedLoad() { // TODO: 在此添加控件通知处理程序代码 LPCTSTR szFilter = _T("信息文件(*.fff)|*.fff|所有文件|*.*||"); //打开对话框 CFileDialog fd(TRUE, _T("*.fff"), NULL, OFN_FILEMUSTEXIST, szFilter, NULL); if (IDCANCEL == fd.DoModal()) return; CFile file; if (!file.Open(fd.GetPathName(), CFile::modeRead)) { MessageBox(_T("打开文件失败!")); return; } SData s; CString str; m_list.DeleteAllItems(); for (int i = 0; file.Read(&s, sizeof(s)) == sizeof(s); ++i) { str.Format(_T("%d"), s.nNumb); m_list.InsertItem(i, str); m_list.SetItemText(i, 1, s.sName); m_list.SetItemText(i, 2, s.date.Format(VAR_DATEVALUEONLY)); } }
2. 用CArchive类读写各种数据类型(它无基类,简单的封装CFile,大量重载了“operator<<”“operator>>”)
void CfffDlg::OnBnClickedSave() { ////另存为对话框 CFileDialog fd(FALSE, _T("*.fff"), _T("example"), OFN_OVERWRITEPROMPT, _T("信息文件(*.fff)|*.fff|所有文件|*.*||"), NULL); if (IDCANCEL == fd.DoModal()) return; CFile file; if (!file.Open(fd.GetPathName(), CFile::modeCreate | CFile::modeWrite)) { MessageBox(_T("保存文件出错!"), _T("Tip")); return; } //通过一个打开状态的文件,构造一个用于保存数据的归档对象 CArchive ar(&file, CArchive::store); int i = 0, nCount = m_list.GetItemCount(); ar << nCount;//先把信息总数(行)保存,以备提取数据 while (i < nCount) { int nNumb = _ttoi(m_list.GetItemText(i, 0)); CString szName = m_list.GetItemText(i, 1); COleDateTime time; time.ParseDateTime(m_list.GetItemText(i, 2)); ar << nNumb << szName << time;//读取数据时严格按照此顺序 ++i; } } void CfffDlg::OnBnClickedLoad() { LPCTSTR szFilter = _T("信息文件(*.fff)|*.fff|所有文件|*.*||"); //打开对话框 CFileDialog fd(TRUE, _T("*.fff"), NULL, OFN_FILEMUSTEXIST, szFilter, NULL); if (IDCANCEL == fd.DoModal()) return; CFile file; if (!file.Open(fd.GetPathName(), CFile::modeRead)) { MessageBox(_T("打开文件失败!")); return; } CArchive ar(&file, CArchive::load); int nCount = 0; ar >> nCount; m_list.DeleteAllItems(); int nNumb = 0; CString szName; COleDateTime time; CString str; int i = 0; while (i < nCount) { ar >> nNumb >> szName >> time; str.Format(_T("%d"), nNumb); m_list.InsertItem(i, str); m_list.SetItemText(i, 1, szName); str = time.Format(VAR_DATEVALUEONLY); m_list.SetItemText(i, 2, str); ++i; } }
3. 用CDocument类序列化(Serialize)存储
新建一个mfc应用程序名为fff,新建一个MFC类 CDoc 继承 CDocument类,并在其虚函数Serialize()函数(是CObject的虚函数,所有CObject的派生类都有此函数)中修改
void CDoc::Serialize(CArchive& ar) { AfxGetMainWnd()->Serialize(ar); //if (ar.IsStoring()) //{ // // TODO: 在此添加存储代码 //} //else //{ // // TODO: 在此添加加载代码 //} }
在CfffDlg类中添加成员变量,CDoc m_doc;
分别在加载函数和保存函数中添加代码,在CfffDlg类中添加虚函数 Serialize 函数
void CfffDlg::OnBnClickedSave() { CFileDialog fd(FALSE, _T("*.fff"), _T("example"), OFN_OVERWRITEPROMPT, _T("信息文件(*.fff)|*.fff|所有文件|*.*||"), NULL); if (IDCANCEL == fd.DoModal()) return; m_doc.OnSaveDocument(fd.GetPathName()); } void CfffDlg::OnBnClickedLoad() { LPCTSTR szFilter = _T("信息文件(*.fff)|*.fff|所有文件|*.*||"); //打开对话框 CFileDialog fd(TRUE, _T("*.fff"), NULL, OFN_FILEMUSTEXIST, szFilter, NULL); if (IDCANCEL == fd.DoModal()) return; m_doc.OnOpenDocument(fd.GetPathName()); } void CfffDlg::Serialize(CArchive& ar) { if (ar.IsStoring()) { // storing code int i = 0, nCount = m_list.GetItemCount(); ar << nCount;//先把信息总数(行)保存,以备提取数据 while (i < nCount) { int nNumb = _ttoi(m_list.GetItemText(i, 0)); CString szName = m_list.GetItemText(i, 1); COleDateTime time; time.ParseDateTime(m_list.GetItemText(i, 2)); ar << nNumb << szName << time;//读取数据时严格按照此顺序 ++i; } } else { // loading code int nCount = 0; ar >> nCount; m_list.DeleteAllItems(); int nNumb = 0; CString szName; COleDateTime time; CString str; int i = 0; while (i < nCount) { ar >> nNumb >> szName >> time; str.Format(_T("%d"), nNumb); m_list.InsertItem(i, str); m_list.SetItemText(i, 1, szName); str = time.Format(VAR_DATEVALUEONLY); m_list.SetItemText(i, 2, str); ++i; } } }
常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。
昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。