关于文件异常捕获--新手篇
来源:互联网 发布:重庆大学网络自助 编辑:程序博客网 时间:2024/06/05 01:50
编写文件IO最主要的是为了支持文档的存储和加载,尽管用CFile对象实现磁盘文档的读写没有什么困难,但大部分MFC应用程序不会这么做,而是用CArchive对象。
1CFile类
CFile是比较简单的类,它封装了Win32用来处理文件IO的那部分。在多于25个的成员函数中有用来打开和关闭文件的函数、读写文件数据的函数、删除和重命名文件的函数、检索文件信息的函数。它的public成员数据之一m_hFile保存了与CFile对象相关联的文件的句柄、protected成员m_strFileName保存着文件的名称。成员函数GetFilePath、GetFileName、GetFileTitle可以用来提取整个文件名或文件名的一部分。例如:如果完整的文件名和路径名为C:/personal/File.txt,那么GetFilePath返回整个字符串,GetFileName返回File.txt,GetFileTitle返回File。
但是如果细讲这些函数,就等于忽略了对编程人员来说CFile拥有的重要功能,即用来读写磁盘文件的函数。下面的几部分简要介绍了CFile的使用方法,以及错误发生时CFile的通知方式(如果从来没有用过C++异常处理,现在开始吧)。
1.1打开关闭和创建文件
用CFile打开文件有2中方法,第一种方法是构造一个没有初始化的CFile对象并调用CFile::Open。下面的代码段就用了这个方法打开一个具有读写访问权的文件File.txt。因为函数的第一个参数没有给出路径名,如果该文件不在当前目录下,Open就会失败。
CFile file;
if(file.Open("File.txt",CFile::modeReadWrite))
{
//It Worked
}
CFile::Open返回一个BOOL值,表示是否成功打开文件。返回非零值意味着文件打开了,零意味着文件没有打开。如果CFile::Open返回零,并且你想知道调用失败的原因,则创建一个CFileException对象并把它的地址传送到Open函数的第三个参数中。
- CFile file;
- CFileException e;
- if(file.Open("File.txt",CFile::modeReadWrite,&e))
- {
- //It Worked
- }
- else
- {
- e.ReportError();//Open failed.Tell the user why.
- }
如果Open失败,则它用“描述失败本质的信息”将CFileException对象初始化。ReportError在该信息的基础上显示一条错误信息通过检查CFileException的公用数据成员m_cause,你可以找出导致失败的原因。详细信息见msdn
第二种方法是用CFile的构造函数打开文件。不必构造一个空的CFile对象并调用Open,可以这样创建一个CFile对象,并用一个语句打开文件:CFile file("File.txt",CFile::modeReadWrite);如果文件不能打开,CFile的构造函数会引发一个CFileException。因此,利用CFile的构造函数打开文件通常使用try和catch块来俘获错误。
- try
- {
- CFile file("File.txt",CFile::modeReadWrite);
- //......
- }
- catch(CFileException* e)
- {
- e->ReportError();
- e->Delete();
- }
是否删除MFC发送给你的CFileException对象,决定权在你。这就是在处理异常后该示例调用Delete删除异常对象的原因。不想调用Delete的唯一场合就是你要用throw重新发送异常,但这种情况很少见。
如果要创建一个新文件而不是打开一个现存文件,则要在CFile::Open或CFile::CFile函数的第二个参数中包含一个CFile::modeCreate标志。CFile file("File.txt",CFile::modeReadWrite | CFile::modeCreate);如果用这种方法创建的文件已经存在,则清空它的内容。
如果要创建一个不存在的文件 或 要在文件存在但没有被截去时打开该文件,则要包含一个CFile::modeNoTruncate标志:CFile file("File.txt",CFile::modeReadWrite | CFile::modeCreate | CFile::modeNoTruncate);按这种方式打开文件基本上总是成功的,因为如果该文件不存在,他能自动生成。
在默认方式下,CFile::Open或CFile::CFile函数打开文件时会获得该文件的独占访问权,也就是说其他人不能再打开该文件。如果有必要,在打开文件时可以指定共享模式,明确的允许其他人访问该文件,如下的几种共享模式。
CFile::shareDenyNone没有读写访问限制、CFile::shareDenyRead禁止读访问权、CFile::shareDenyWrite禁止写访问权、CFile::shareExclusive禁止读写访问权(默认值)。还要3种读写访问权CFile::modeReadWrite请求读写访问权、CFile::modeRead请求读访问权、CFile::modeWrite请求写访问权。这些选项的常见用法是允许任一客户读取文件,但禁止往文件上写。
关闭打开的文件有2种方式。如果要显式关闭文件,则对应的CFile对象调用Close函数。如果你喜欢,可以用CFile的析构函数关闭文件。如果文件还没有关闭,类的析构函数则调用Close。这就是说,在堆上创建的CFile对象在失效后会自动关闭。有时程序员显示调用Close的原因是:关闭当前处于打开状态的文件,以便用同一个CFile对象打开另一个文件。
1.2读和写
可以用CFile::Read读一个具有访问权的打开文件。可以用CFile::Write写一个具有写访问权的打开文件。下面的示例分配一个4KB的文件IO缓冲,并一次读取4KB内容,转换为小写字母后再写回文件。如下:
- //创建文件并写入文件内容
- char ch[]="ABCDEFGHIJKLMN";
- CFile file("1.txt",CFile::modeCreate | CFile::modeReadWrite | CFile::modeNoTruncate);
- file.Write(ch,sizeof(ch));
- //注意:移动文件指针到文件开头
- file.SeekToBegin();
- //接着读取文件内容到自己定义的缓冲区内
- BYTE buffer[0x1000];
- DWORD dwBytesRemaining=file.GetLength();
- while(dwBytesRemaining)
- {
- DWORD dwPosition=file.GetPosition();
- UINT nByteRead=file.Read(buffer,sizeof(buffer));
- ::CharLowerBuff((char*)buffer,nByteRead);
- file.Seek(dwPosition,CFile::begin);
- file.Write(buffer,nByteRead);
- dwBytesRemaining-=nByteRead;
- }
- MessageBox((char*)buffer);
- //最后关闭文件,也可以不用自己调用该函数,而由CFile的析构函数来做这个工作
- file.Close();
如果在文件IO过程中有错误发生,Read、Write、和其它CFile函数就会发送一个CFileException。CFileException::m_Cause告诉你引发错误的原因。例如:试图向已满的磁盘上写文件会引发CFileException,其中m_Cause等于CFileException::diskFull。试图在文件范围之外读取数据会引发CFileException,其中m_Cause等于CFileException::endOfFile.
如果你不捕获CFile成员函数发送的异常,MFC会替你捕获它们。MFC给未处理的异常配有默认处理程序,该程序调用ReportError显示一条描述错误的信息。然而,一般情况下,最好捕获文件IO异常,防止代码的关键部分被遗漏
例:
CString strFileName = “D:\\bak\\test.txt”;
TRY
{
CFile f(strFileName,CFile::modeCreate | CFile::modeWrite);
}
CATCH( CFileException e )
{
if( e->m_cause == CFileException::fileNotFound )
printf( "ERROR: File not found\n");
else if( e->m_cause == CFileException:: diskFull)
printf( "ERROR: Disk full\n");
else if( e->m_cause == CFileException:: endOfFile)
printf( "ERROR: End Of File\n");
}
注:
m_cause可能为以下值
CFileException::none: 没有错误发生。
CFileException::generic: 未指定的错误。
CFileException::fileNotFound : 文件找不到错误。
CFileException::badPath : 全部或部分路径无效。
CFileException::tooManyOpenFiles:超出允许打开的文件数目。
CFileException::accessDenied : 不能访问文件。
CFileException::invalidFile : 试图访问一个无效的文件。
CFileException::removeCurrentDir:试图删除正在操作的目录。
CFileException::directoryFull: 目录个数已满。
CFileException::badSeek : 试图设置文件位置指针出错。
CFileException::hardIO : 硬件出错。
CFileException::sharingViolation : 共享出错。
CFileException::lockViolation : 试图锁定已锁定的区域。
CFileException::diskFull : 磁盘空间已满。
CFileException::endOfFile : 到达文件结尾。
- 关于文件异常捕获--新手篇
- 关于异常捕获
- 关于 捕获异常 技巧
- 关于异常捕获那些事
- 关于异常捕获的问题
- Android捕获异常,生成文件
- 关于构造中new的异常捕获!
- 关于正则匹配的异常捕获
- 关于 捕获异常 技巧 自己总结!!!!!!!!
- 关于未捕获异常的处理(WPF)
- 关于异常捕获后程序的去向
- 关于未捕获异常的处理(WPF)
- 关于异常捕获 try catch的说明
- 关于捕获崩溃异常并保持记录
- 关于未捕获异常的处理(WPF)
- 捕获异常并生成minidump文件
- AS3加载文件时的异常捕获
- SpringMVC上传文件过大,异常捕获问题。
- WinForm分页控件
- set::insert
- 看〈快乐的大脚〉
- find_first_of()和 find_last_of()
- IM 开源项目 群组服务 数据库设计 (01)
- 关于文件异常捕获--新手篇
- 『C程序设计』读书笔记
- Android 之 内存管理
- Sicily1031. Campus
- linux蓝牙配置
- 设置UIButton字体的大小
- (转)写代码如坐禅:你是哪一类程序员
- Temporary Variable in C++
- wav文件格式分析详解