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实现简单字符串文件操作

如果你要操作的文件知识文本字符串,并且文件不大,使用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);
	}


  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值