MFC文件的读写操作,类的序列化与反序列化,CFile,CFileDialog,CArchive,CStdioFile

来源:互联网 发布:淘宝如何抢秒杀商品 编辑:程序博客网 时间:2024/05/21 17:39

一,使用CFileDialog文件对话框

对话框仅仅是为了获得将要打开文件或保存文件的名称和路径,当然还会有文件的后缀过滤器。代码如下:

/*打开文件对话框*/CString filter;//MFC的字符串类filter = "文本文档(*.txt)|*.txt||";//文件名称过滤器CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter);//设置为TRUE为打开文件对话框if (dlg.DoModal() == IDOK)//判断是否成功点击确定{CString strPath;//文件路径strPath = dlg.GetPathName();//获取文件路径//TODO 根据文件路径strPath你可以读取数据</span>MessageBox(strPath);}


保存文件对话框,只需要秀修改CFileDialog的构造方法的第一个参数为FALSE就行了。

二,使用CArchive和CFile对文件进行读写操作

CArchive类是对文件操作的工具类,它很方便的实现了CFile的很多功能,代码如下:

/*读取文件*/CString filter;filter = "文本文档(*.txt)|*.txt||";//文件名称过滤器CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter);//设置为TRUE为打开文件对话框if (dlg.DoModal() == IDOK)//判断是否成功点击确定{CString strPath;//文件路径strPath = dlg.GetPathName();//获取文件路径//todo 将本地文件载入内存CFile mFile;if (mFile.Open(strPath, CFile::modeRead) == 0)//已read方式打开文件return;char buf[512];//缓冲为512,我要保存的类很小,也很少CArchive ar(&mFile, CArchive::load, 512, buf);//创建CArchive,模式为load就是read//ar >> str_txt;//二进制读取,如果是文本,读取会出问题,第一个字符会乱码,有时候还会文件指针越界ar.ReadString(str_txt);//读取数据并保存到str_txt数组中//ar.Flush();//清理缓冲区,写入本地ar.Close();mFile.Close();MessageBox(strPath);//弹出文件路径}}

</pre><pre>
/*保存文件*/CString filter;filter = "文本文档(*.txt)|*.txt||";CFileDialog dlg(FALSE, NULL, NULL, OFN_HIDEREADONLY, filter);if (dlg.DoModal() == IDOK){CString strPath;strPath = dlg.GetPathName();//todo 将内存中的文件保存到本地CFile mFile;mFile.Open(strPath, CFile::modeCreate | CFile::modeWrite);CArchive ar(&mFile, CArchive::store);//类似write//ar << str_txt;//二进制读写ar.WriteString(str_txt);//字符串读写ar.Close();mFile.Close();MessageBox(strPath);}


三,使用CStdioFile实现简单字符串文件操作

如果你要操作的文件知识文本字符串,并且文件不大,使用CStdioFile将更加方便,代码如下:

/*读取文件*/CString filter;filter = "文本文档(*.txt)|*.txt||";CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter);if (dlg.DoModal() == IDOK){CString strPath;strPath = dlg.GetPathName();CStdioFile mFile;//简单文本文件的读写CFileException mExcept;//文件异常,我没有使用mFile.Open(strPath, CFile::modeRead);if (mFile == NULL)return;mFile.ReadString(str_txt);mFile.Close();MessageBox(strPath);}

<strong></strong>/*保存文件*/CString filter;filter = "文本文档(*.txt)|*.txt||";CFileDialog dlg(FALSE, NULL, NULL, OFN_HIDEREADONLY, filter);if (dlg.DoModal() == IDOK){CString strPath;strPath = dlg.GetPathName();CStdioFile mFile;CFileException mExcept;mFile.Open(strPath, CFile::modeWrite, &mExcept);CString string = L"I am a string by append";mFile.SeekToEnd();//可以跳到文件末尾,而CArchive没有这个功能//mFile.SeekToBegin();//可以跳到文件开头,而CArchive没有这个功能mFile.WriteString(string);mFile.Close();MessageBox(strPath);}


四,使用CArchive和CObject.Serialize()实现对象序列化和反序列化

主要包括两部分,可序列化类的声明,类的本地保存和读取(序列化和反序列化)。

1,声明可序列化类,分为.h文件和.cpp文件,代码如下:

#pragma onceclass Student:public CObject //第一步 继承CObject类{public:DECLARE_SERIAL(Student); //第二部 使用宏声明当前创建类是序列化类Student();~Student();virtual void Serialize(CArchive& archive); //第三部 重写序列化方法CString name;char sex;unsigned int age;};
#include "stdafx.h"#include "Student.h"IMPLEMENT_SERIAL(Student, CObject, 1)//第四步 建立版本标识,类似于ID,多个不同的类序列化时,数字不要重复Student::Student(){}Student::~Student(){}void Student::Serialize(CArchive& archive)//第五步 实现序列化方法{CObject::Serialize(archive);if (archive.IsStoring())//判断是否是写到文件即序列化archive << name << sex << age;//将属性保存到文件elsearchive >> name >> sex >> age;//将属性读取到程序}

2,类的本地保存和读取(序列化和反序列化),代码如下:

/*读取文件到程序*/CString filter;filter = "文本文档(*.txt)|*.txt||";CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter);if (dlg.DoModal() == IDOK){CString strPath;strPath = dlg.GetPathName();//todo 将本地文件载入内存CFile mFile;if (mFile.Open(strPath, CFile::modeRead) == 0)return;char buf[512];CArchive ar(&mFile, CArchive::load, 512, buf);unsigned long length = ar.ReadCount();//读取存储的数据单元个数,因为我们是首先写的,所以必须首先读Student* stu;for (int i = 0; i < length;i++)stu = (Student*)ar.ReadObject(RUNTIME_CLASS(Student));//读取一个类信息,同时指针移动到下一个类信息开始,我们读取最后一个ar.Close();mFile.Close();MessageBox(strPath);}
/*保存对象到文件中*/CString filter;filter = "文本文档(*.txt)|*.txt||";CFileDialog dlg(FALSE, NULL, NULL, OFN_HIDEREADONLY, filter);if (dlg.DoModal() == IDOK){CString strPath;strPath = dlg.GetPathName();//todo 将本地文件载入内存CFile mFile;if (mFile.Open(strPath, CFile::modeCreate|CFile::modeWrite) == 0)//文件的打开模式中间使用的|一个竖杠return;char buf[512];CArchive ar(&mFile, CArchive::store, 512, buf);Student stu;stu.age = 99;stu.name = L"徐凯文";stu.sex = 'm';ar.WriteCount(1);//首先写入我们将要写入的数据单元个数,便于读取的时候,判断个数ar.WriteObject(&stu);//写入文件ar.Close();mFile.Close();MessageBox(strPath);}


5 0
原创粉丝点击