【48】MFC入门到精通——MFC 文件读写总结 CFile、CStdioFile、CFileDialog

发布于:2025-07-20 ⋅ 阅读:(17) ⋅ 点赞:(0)

MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘输入输出功能。通过他的派生类可以间接的支持文本、文件、内存文件等。

1 打开文件

通过对CFile类的初始化,即可完成文件的打开

//两个参数表示 文件名和打开方式
CFile(LPCTSTR lpszFileName, UINT nOpenFlags);

1.2 打开文件模式总结

CFile打开文件模式总结

在这里插入图片描述

2 常用函数

2.1 写文件

写文件时,需调用类的Write函数

void CFile::Write(const void* lpBuf, UINT nCount);
  • 参数lpBuf:写入数据的缓冲区

  • 参数nCount:写入数据的字符数

2.2 读文件

读文件时,调用类的Read函数

UINT CFile::Read(void* lpBuf, UINT nCount);
  • 参数lpBuf:接收读取数据的缓冲区

  • 参数nCount:要读取数据的字符数

  • 返回值:返回读取到缓冲区的字节数

在文件操作完毕后需要调用Close函数来关闭文件,如果在销毁对象之前尚未关闭文件,析构函数将为您关闭该文件。如果使用new在堆上分配对象,则必须在关闭 file.setsto 后将其删除。

2.3 获取文件长度

我们可以使用CFile类的GetLength函数来获取文件的长度

virtual ULONGLONG CFile::GetLength() const;

该函数可以返回我们打开的文件长度

3. 文件打开读写实力

3.1 写文件 覆盖写

文件流类CFile—数据写入文件

实例化一个对象

对象使用open()函数打开文件,参数为文件路径和打开类型

数据写入文件使用Write()

关闭文件流Close()
void CMFCApplication1Dlg::OnBnClickedButton7()
{
	// TODO: 在此添加控件通知处理程序代码
	CString sname = _T("zhangsan");
	CString FileName = _T("D:\\Projects\\Programming_test\\test.txt");
	CFile fout;
	fout.Open(FileName, CFile::modeCreate + CFile::modeWrite); //直接构建创建一个新文件。如果该文件已经存在,则文件内容自动被清零。
	int len = sname.GetLength();
	fout.Write(sname, len * 2);//CString每个字符占2个字节,所以存储长度乘以2
	fout.Close();
}

在这里插入图片描述

3.2 文尾追加写

但上面面的写法存在问题,
问题:每录入一次信息,前面的数据就会被删除,如何解决数据被删除覆盖?
问题根源:因为每一次打开文件,文件写指针都是在文件的开头,所以数据会被删除覆盖。

(1)增加打开模式 表示追加

CFile::modeNoTruncate

该值一般modeCreate组合使用。如果创建的文件已经存在,那么它不会被清零。因而该文件能可靠的打开,或者新建一个文件或者打开一个现存文件。这对于打开一个可能存在可能不存在的设置文件十分有用。该选项通用可用于CStdioFile。

(2)文尾定位指针

CFile::SeekToEnd()

把文件指针定位至尾部

fout.SeekToEnd();

CFile::modeNoTruncate 和 CFile::SeekToEnd() 配合使用才能追加写。

void CMFCApplication1Dlg::OnBnClickedButton7()
{
	// TODO: 在此添加控件通知处理程序代码
	CString sname = _T("zhangsan");
	CString FileName = _T("D:\\Projects\\Programming_test\\test.txt");
	CFile fout;
	fout.Open(FileName, CFile::modeCreate + CFile::modeWrite+ CFile::modeNoTruncate);//新建或者打开一个现存文件,追加写
	int len = sname.GetLength();

	//CFile::modeNoTruncate,表示追加
	// .SeekToEnd();表示在文件末尾插入。
	fout.SeekToEnd(); 
	fout.Write(sname, len * 2);//加1代表多一个空格来间隔数据
	fout.Close();
}

在这里插入图片描述

3.3 换行写

fout.Write("\n",1);

完整的输入数据的代码

void CMFCApplication1Dlg::OnBnClickedButton7()
{
	// TODO: 在此添加控件通知处理程序代码
	CString sname = _T("zhangsan");
	CString FileName = _T("D:\\Projects\\Programming_test\\test.txt");
	CFile fout;
	fout.Open(FileName, CFile::modeCreate + CFile::modeWrite+ CFile::modeNoTruncate);//新建或者打开一个现存文件,追加写
	int len = sname.GetLength();

	//CFile::modeNoTruncate,表示追加
	// .SeekToEnd();表示在文件末尾插入。
	fout.SeekToEnd(); 
	fout.Write(sname, len * 2);//加1代表多一个空格来间隔数据
	fout.Write(_T("\r\n"),1);//数据换行
	fout.Close();
}

可以换行写了,但有个问题,每个字符之间有个空格
在这里插入图片描述

上写入的是CString字符,我们看一下

将写入的字符换位 cahr * ,正常了.

void CMFCApplication1Dlg::OnBnClickedButton7()
{
	// TODO: 在此添加控件通知处理程序代码
	char sname[] = "zhangsan";
	CString FileName = _T("D:\\Projects\\Programming_test\\test.txt");
	CFile fout;
	fout.Open(FileName, CFile::modeCreate + CFile::modeWrite+ CFile::modeNoTruncate);//新建或者打开一个现存文件,追加写

	//CFile::modeNoTruncate,表示追加
	// .SeekToEnd();表示在文件末尾插入。
	fout.SeekToEnd(); 
	
	fout.Write(sname, strlen(sname));//加1代表多一个空格来间隔数据
	fout.Write(_T("\r\n"), 1);//数据换行
	fout.Close();
}

在这里插入图片描述

4 文件对话框 CFileDialog

MFC 文件对话框 CFileDialog (打开文件 和 保存文件 对话框)

有时候我们希望能动态更改文件的读写位置,那么就可以使用CFileDialog类来实现这一功能。

CFileDialog类封装了Windows常用的文件对话框。常用的文件对话框提供了一种简单的与Windows标准相一致的文件打开和文件存盘对话框功能。

4.2 文件对话框实例

根据前面所讲内容,给大家做个文件对话框实例。

1.创建一个基于对话框的MFC应用程序工程,名称设为“MFCTest”。

2.修改主对话框IDD_MFCTEST_DIALOG的模板,删除自动生成的“TODO: Place dialog controls here.”静态文本框,

添加两个编辑框,ID分别为IDC_OPEN_EDIT和IDC_SAVE_EDIT,
再添加两个按钮,ID分别设为IDC_OPEN_BUTTON和IDC_SAVE_BUTTON,
Caption(描述文字)分别设为“打开”和“保存”。

按钮IDC_OPEN_BUTTON用于显示打开文件对话框,编辑框IDC_OPEN_EDIT显示在打开文件对话框中选择的文件路径。
按钮IDC_SAVE_BUTTON用于显示保存文件对话框,编辑框IDC_SAVE_BUTTON显示在保存文件对话框中选择的文件路径。

3.分别为按钮IDC_OPEN_BUTTON和IDC_SAVE_BUTTON添加点击消息的消息处理函数
双击 打开 和 保存 按钮 进入到CMFCTestDlg::OnBnClickedOpenButton()和CMFCTestDlg::OnBnClickedSaveButton()函数

4.修改两个消息处理函数如下:

void CMFCTestDlg::OnBnClickedOpenButton()
{
	// TODO: 在此添加控件通知处理程序代码

	// 设置过滤器
	TCHAR szFilter[] = _T("文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||");

	// 构造打开文件对话框 (TRUE创建打开文件对话框)
	CFileDialog fileDlg(TRUE,_T("txt"),NULL,0,szFilter,this);
	CString strFilePath;

	// 显示打开文件对话框
	if (IDOK == fileDlg.DoModal())
	{
		// 如果点击了文件对话框上的“打开”按钮,则将选择的文件路径显示到编辑框里
		strFilePath = fileDlg.GetPathName();
		SetDlgItemText(IDC_OPEN_EDIT,strFilePath);

		//读取并显示文件内容
		CFile file(strFilePath, CFile::modeRead);
		char* pBuf;
		DWORD dwFileLen = file.GetLength();
		pBuf = new char[dwFileLen + 1];
		pBuf[dwFileLen] = 0;
		file.Read(pBuf, dwFileLen);
		USES_CONVERSION;
		CString strBuf = A2W(pBuf);
		MessageBox(strBuf);
		file.Close();
	}
}


void CMFCTestDlg::OnBnClickedSaveButton()
{
	// TODO: 在此添加控件通知处理程序代码

	// 设置过滤器
	TCHAR szFilter[] = _T("文本文件(*.txt)|*.txt|Word文件(*.doc)|*.doc|所有文件(*.*)|*.*||");

	// 构造保存文件对话框(FALSE创建保存文件对话框。)
	CFileDialog fileDlg(FALSE, _T("doc"),_T("my"),OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, szFilter, this);
	CString strFilePath;

	// 显示保存文件对话框
	if (IDOK == fileDlg.DoModal())
	{
		// 如果点击了文件对话框上的“保存”按钮,则将选择的文件路径显示到编辑框里
		strFilePath = fileDlg.GetPathName();
		SetDlgItemText(IDC_SAVE_EDIT, strFilePath);

		//简单的写入文件
		CFile file;
		file.Open(strFilePath, CFile::modeCreate + CFile::modeWrite + CFile::modeNoTruncate);//新建或者打开一个现存文件,追加写
		file.Write("Tom and Jerry", strlen("Tom and Jerry"));
		file.Close();
	}
}

上面显示编辑框内容时,使用了Windows API函数SetDlgItemText,当然也可以先给编辑框关联变量,然后再使用在创建对话框类和添加控件变量中介绍的
CDialogEx::UpdateData()函数,但是比较习惯使用SetDlgItemText函数,感觉比较灵活。

5.运行此程序
在这里插入图片描述

在结果对话框上点“保存”按钮,显示保存文件对话框如下:
在这里插入图片描述

在这里插入图片描述

在打开文件
在这里插入图片描述

在这里插入图片描述

到此,文件对话框就讲完了,是不是依然很简单?如果忘记了文件对话框类构造函数的参数意义,可以回到来看看或者在MSDN上查阅。

MFC 文件对话框-打开文件-保存文件 代码下载

5 CStdioFile 类 读写CSting

CStdioFile继承自CFile,它可以建立一个CStdioFile 对象,更好的读写CSting;

CStdioFile定义在"afx.h"头文件中,因此在使用该类之前需要先引入该头文件。

CString CMFCApplication1Dlg::ReadCString()
{
	CStdioFile file;
	//CStdioFile继承自CFile,它可以建立一个CStdioFile 对象
	CString FileName = _T("D:\\Projects\\Programming_test\\test.txt");
	if (!file.Open(FileName, CFile::modeRead))//新建或者打开一个现存文件,追加写
	{
		return 0;
	}

	CString  strLine = _T("");
	CString str;
	while (file.ReadString(strLine))
	{
		//输出处理结果
		GetDlgItemText(IDC_STATIC_LOG, str);//获取已显示的文本
		str = str + _T("\r\n") + strLine;//加换行、加新的文本,ICR_Process_result即新的文件内容
		SetDlgItemText(IDC_STATIC_LOG, str);
	}
	
	file.Close();

	return str;
}


int CMFCApplication1Dlg::WriteCStr()
{
	CStdioFile file;
	//CStdioFile继承自CFile,它可以建立一个CStdioFile 对象
	CString FileName = _T("D:\\Projects\\Programming_test\\test.txt");
	if (!file.Open(FileName, CFile::modeCreate + CFile::modeWrite + CFile::modeNoTruncate))//新建或者打开一个现存文件,追加写
	{
		return 0;
	}

	CString s1 = _T("#sIpAddress\n");
	CString s2 = _T("192.168.1.64\n");
	CString s3 = _T("#sUserID\n");
	CString s4 = _T("admin\n");
	CString s5 = _T("#sPassword\n");
	CString s6 = _T("abcd1234\n");


	file.WriteString(s1);
	file.WriteString(s2);
	file.WriteString(s3);
	file.WriteString(s4);
	file.WriteString(s5);
	file.WriteString(s6);

	file.Close();

	return 0;
}

void CMFCApplication1Dlg::OnBnClickedButtonReadcstr()
{
	// TODO: 在此添加控件通知处理程序代码
	ReadCString();
}


void CMFCApplication1Dlg::OnBnClickedButtonWritecstr()
{
	// TODO: 在此添加控件通知处理程序代码
	WriteCStr();
}

在这里插入图片描述

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到