MFC文件的读写操作,类的序列化与反序列化,CFile,CFileDialog,CArchive,CStdioFile
Posted 晴堂
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC文件的读写操作,类的序列化与反序列化,CFile,CFileDialog,CArchive,CStdioFile相关的知识,希望对你有一定的参考价值。
一,使用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将更加方便,代码如下:
/*读取文件*/
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 once
class 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;//将属性保存到文件
else
archive >> 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);
以上是关于MFC文件的读写操作,类的序列化与反序列化,CFile,CFileDialog,CArchive,CStdioFile的主要内容,如果未能解决你的问题,请参考以下文章
Java学习笔记6.3.3 文件操作 - 对象序列化与反序列化