c++ mfc CFile+CArchive 简单实践

1 概要

1.1CFile(源码)

MFC提供了CFile类方便文件的读写,首先要知道,文件的数据读取、数据写入与文件指针的操作都是以字节为单位的,数据的读取和写入都是从文件指针的位置开始的,当打开一个文件的时候,文件指针总是在文件的开头。常规方法如下:

CFile file;

file.open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL );

//lpszFileName是文件名,可包含文件路径,若只有文件名,则默认路径为工程路径,nOpenFlags是文件打开模式,pError是打开失败时用来接收失败信息,一般设置为NULL。

1.2 CArchive

当我们创建对象的时候,对象就存在于内存中,当其生命周期结束后,这些被创建的对象就要被销毁;当对象被销毁后,我们就无法知道这些对象的值。MFC提供了CArchive类可以将对象数据保存到永久设备,比如磁盘文件。当应用程序重新启动后,CArchive类可以帮助我们从磁盘文件读取这些数据,然后在内存中重新构建对应的对象;这样就使得我们的对象数据永久存在,该过程称之为序列化(或者串行化)。

 

 

2 代码

2.1 摘要

double g_data1 = 0.0;
double g_data2 = 0.0;
double g_data3 = 0.0;
int g_ndata = 0;

void CCFileTestDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here

	CString data1,data2,data3,data4;
	CFile SetFile;
	if(SetFile.Open(_T("setfujiandata.ini"),CFile::modeRead))
	{	
		CArchive ar(&SetFile,CArchive::load);
		try
		{
			ar >> data1;
			ar >> data2;
			ar >> data3;
			ar >> data4;
		}
		catch(CArchiveException* e)
		{
			e->ReportError();
			e->Delete();
			ar.Close();
			SetFile.Close();
		}
		ar.Close();
		SetFile.Close();
		g_data1 = atof(data1);
		g_data2 = atof(data2);
		g_data3 = atof(data3);
		g_ndata = atoi(data4);

		SetDlgItemText(IDC_EDIT1,data1);
		SetDlgItemText(IDC_EDIT2,data2);
		SetDlgItemText(IDC_EDIT3,data3);
		SetDlgItemText(IDC_EDIT4,data4);
	}
}

void CCFileTestDlg::OnButton2() 
{
	// TODO: Add your control notification handler code here
	// TODO: 在此添加控件通知处理程序代码
	CString data1,data2,data3,data4;

	GetDlgItemText(IDC_EDIT1,data1);
	GetDlgItemText(IDC_EDIT2,data2);
	GetDlgItemText(IDC_EDIT3,data3);
	GetDlgItemText(IDC_EDIT4,data4);
	CFile SetFile;
	if(SetFile.Open(_T("setfujiandata.ini"),CFile::modeCreate|CFile::modeWrite))
	{	
		CArchive ar(&SetFile,CArchive::store);
		try
		{
			ar << data1;
			ar << data2;
			ar << data3;
			ar << data4;
		}
		catch(CArchiveException* e)
		{
			e->ReportError();
			e->Delete();
			ar.Close();
			SetFile.Close();
		}

		g_data1 = atof(data1);
		g_data2 = atof(data2);
		g_data3 = atof(data3);
		g_ndata = atof(data4);
		ar.Close();
		SetFile.Close();

		//g_bSet = true;
		MessageBox(_T("保存成功!"));
	}
	else
	{
		MessageBox(_T("保存失败!"));
	}
}

void CCFileTestDlg::OnButton4() 
{
	// TODO: Add your control notification handler code here
	SetDlgItemText(IDC_EDIT1,"");
	SetDlgItemText(IDC_EDIT2,"");
	SetDlgItemText(IDC_EDIT3,"");
	SetDlgItemText(IDC_EDIT4,"");
}

2.2 代码

// CFileTestDlg.cpp : implementation file
//

#include "stdafx.h"
#include "CFileTest.h"
#include "CFileTestDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CAboutDlg dialog used for App About


class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CCFileTestDlg dialog

CCFileTestDlg::CCFileTestDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CCFileTestDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CCFileTestDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CCFileTestDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCFileTestDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CCFileTestDlg, CDialog)
	//{{AFX_MSG_MAP(CCFileTestDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	ON_BN_CLICKED(IDC_BUTTON4, OnButton4)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CCFileTestDlg message handlers

BOOL CCFileTestDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CCFileTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CCFileTestDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CCFileTestDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

double g_data1 = 0.0;
double g_data2 = 0.0;
double g_data3 = 0.0;
int g_ndata = 0;

void CCFileTestDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here

	CString data1,data2,data3,data4;
	CFile SetFile;
	if(SetFile.Open(_T("setfujiandata.ini"),CFile::modeRead))
	{	
		CArchive ar(&SetFile,CArchive::load);
		try
		{
			ar >> data1;
			ar >> data2;
			ar >> data3;
			ar >> data4;
		}
		catch(CArchiveException* e)
		{
			e->ReportError();
			e->Delete();
			ar.Close();
			SetFile.Close();
		}
		ar.Close();
		SetFile.Close();
		g_data1 = atof(data1);
		g_data2 = atof(data2);
		g_data3 = atof(data3);
		g_ndata = atoi(data4);

		SetDlgItemText(IDC_EDIT1,data1);
		SetDlgItemText(IDC_EDIT2,data2);
		SetDlgItemText(IDC_EDIT3,data3);
		SetDlgItemText(IDC_EDIT4,data4);
	}
}

void CCFileTestDlg::OnButton2() 
{
	// TODO: Add your control notification handler code here
	// TODO: 在此添加控件通知处理程序代码
	CString data1,data2,data3,data4;

	GetDlgItemText(IDC_EDIT1,data1);
	GetDlgItemText(IDC_EDIT2,data2);
	GetDlgItemText(IDC_EDIT3,data3);
	GetDlgItemText(IDC_EDIT4,data4);
	CFile SetFile;
	if(SetFile.Open(_T("setfujiandata.ini"),CFile::modeCreate|CFile::modeWrite))
	{	
		CArchive ar(&SetFile,CArchive::store);
		try
		{
			ar << data1;
			ar << data2;
			ar << data3;
			ar << data4;
		}
		catch(CArchiveException* e)
		{
			e->ReportError();
			e->Delete();
			ar.Close();
			SetFile.Close();
		}

		g_data1 = atof(data1);
		g_data2 = atof(data2);
		g_data3 = atof(data3);
		g_ndata = atof(data4);
		ar.Close();
		SetFile.Close();

		//g_bSet = true;
		MessageBox(_T("保存成功!"));
	}
	else
	{
		MessageBox(_T("保存失败!"));
	}
}

void CCFileTestDlg::OnButton4() 
{
	// TODO: Add your control notification handler code here
	SetDlgItemText(IDC_EDIT1,"");
	SetDlgItemText(IDC_EDIT2,"");
	SetDlgItemText(IDC_EDIT3,"");
	SetDlgItemText(IDC_EDIT4,"");
}

3. 运行

4. 引用

4.1 CFile

https://blog.csdn.net/zhang_fei_fresh/article/details/76408636 

4.2 CArchive

https://blog.csdn.net/c_base_jin/article/details/55060720

https://baike.baidu.com/item/CArchive/9600368?fr=aladdin

https://www.cnblogs.com/lujin49/p/4967417.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CArchiveMFC(Microsoft Foundation Classes)中的一个类,用于在C++中进行序列化和反序列化操作。它提供了一种方便的方式来将对象的数据保存到文件或者从文件中读取数据。 使用CArchive进行序列化和反序列化的步骤如下: 1. 创建一个CArchive对象,并指定要进行操作的文件和打开模式(读或写)。 2. 使用CArchive对象的成员函数来读取或写入数据。可以使用<<和>>操作符来序列化和反序列化基本数据类型,也可以使用WriteObject和ReadObject函数来序列化和反序列化自定义的对象。 3. 关闭CArchive对象。 下面是一个简单的示例代码,演示了如何使用CArchive进行序列化和反序列化: ```cpp #include <afx.h> // 包含MFC头文件 class MyData { public: int value1; float value2; CString value3; // 序列化函数 void Serialize(CArchive& ar) { if (ar.IsStoring()) { ar << value1 << value2 << value3; } else { ar >> value1 >> value2 >> value3; } } }; int main() { // 创建一个CArchive对象,并指定要进行操作的文件和打开模式 CFile file(_T("data.dat"), CFile::modeCreate | CFile::modeReadWrite); CArchive ar(&file, CArchive::store); // 创建一个自定义对象 MyData data; data.value1 = 10; data.value2 = 3.14f; data.value3 = _T("Hello, CArchive!"); // 序列化对象到文件 data.Serialize(ar); // 关闭CArchive对象 ar.Close(); file.Close(); // 重新打开文件进行反序列化 file.Open(_T("data.dat"), CFile::modeRead); ar.SetFile(&file, CArchive::load); // 反序列化对象 MyData newData; newData.Serialize(ar); // 关闭CArchive对象 ar.Close(); file.Close(); // 输出反序列化后的数据 printf("value1: %d\n", newData.value1); printf("value2: %f\n", newData.value2); printf("value3: %s\n", newData.value3); return 0; } ``` 以上代码中,首先创建了一个CArchive对象ar,并指定了要进行操作的文件和打开模式。然后,创建了一个自定义的对象data,并调用其Serialize函数将数据序列化到CArchive对象中。接着,关闭CArchive对象和文件。然后,重新打开文件进行反序列化,创建一个新的对象newData,并调用其Serialize函数从CArchive对象中反序列化数据。最后,关闭CArchive对象和文件,并输出反序列化后的数据。 需要注意的是,CArchive类是MFC中的一个类,因此在使用CArchive之前,需要先包含MFC的头文件。另外,CArchive类的使用需要在MFC环境中进行,不能在纯C++环境中使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值