文章目录
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上查阅。
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();
}