第 43 章
盘硬件,因此会产生各种各样的异常。无论是文件的
打开、读写、定位还是关闭cāo作都会产生异常。异常通常是由调用的函数抛出,在TRY/CATCH
块中捕获,此外CFile::Open()函数还可以用参数的形式获得异常的指针。
MFC 中文件的异常类是CFileException。CFileException 对象可以获得文件cāo作失败的原
因代码。该对象在CFile 成员函数中被创建和产生,也可以在CFile 派生类的成员函数中创建
和产生。程序用CATCH 表达式获取这一对象。CFileException 类包含可移植的原因代码和cāo
作系统制定的错误值的公共成员变量。一般情况下使用可移植的原因代码以实现平台的无关
xìng。
下面对CFileException 相关cāo作进行介绍,包括如何创建、抛出和获得异常。
1.创建并抛出异常
MFC 不允许手动创建CFileException 对象,而采用AfxThrowFileException()函数创建并
抛出文件异常。AfxThrowFileException()函数的原型为:
void AfxThrowFileException(
int cause,
LONG lOsError = -1,
LPCTSTR lpszFileNcom = NULL
);
? 参数cause:指定异常的原因,是一个枚举类型,具体枚举值如表8-2 所示。
? 参数lOsError:指定一个跟cāo作系统相关的异常原因。注意该值需要程序自行提供,
cāo作系统并不自动设置该值。
? 参数lpszFileNcom:指定出错的文件名。
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·196·
表8-2 文件异常原因代码
cause 取值 取值说明
CFileException::none 没有错误发生
CFileException::generic 一个没有特定意义的错误发生
CFileException::fileNotFound 无法找到文件
CFileExceptionLLbadPath 路径错误
CFileException::tooManyOpenFiles 超出允许的打开文件的最大数目
CFileException::accessDenied 文件无法访问
CFileException::invalidFile 尝试使用一个无效的文件句柄
CFileException::removeCurrentDir 当前工作目录无法被删除
CFileException::directoryFull 没有更多的目录项
CFileException::badSeek 移动文件指针错误
CFileException::hardIO 硬件错误
CFileException::sharingViolation 共享错误
CFileException::lockViolation 锁定错误
CFileException::diskFull 磁盘已满
CFileException::endOfFile 到达文件末尾
用户可以在自定义函数中添加自定义语句AfxThrowFileException 以抛出自定义的文件
异常,例如有一个CSampleFile 类用于指定存取一个有最大长度的文件,这个最大长度设置
为m_dwMaxLength,如果超出这个长度,就存取失败。下面给出一个写文件的例子,如果写
入的数据使得文件长度超出m_dwMaxLength,则模拟磁盘满的出错异常。
//向文件中写入字符串lpszString
void CSampleFile::WriteString(LPCTSTR lpszString)
{
//m_File 是CSampleFile 的成员变量
DWORD dwLen=m_File.GetLength()+strlen(lpszString)+1;//获得写入后的文件大小
if (dwLen>m_dwMaxLength)
AfxThrowFileException(CFileException::diskFull); //抛出磁盘满的异常
m_File.Write(lpszString,strlen(lpszString)+1); //如果没超过限度,则写入文件
}
2.获得文件异常信息
从第1 部分创建CFileException 异常中可以看出,文件异常有3 类不同的信息,分别由
3 个成员变量表示。
? CFileException::m_cause : int 类型, 获得可移植的出错代码, 这些代码同前面
AfxThrowFileException()函数的参数cause 的代码相同。
? CFileException::m_lOsError:long 类型,获得cāo作系统指定的出错代码。
? CFileException::m_strFileNcom:CString 类型,获得出错的文件名。
下面给出用TRY/CATCH 块获得文件异常信息的示例代码:
TRY
{
//创建文件进行写入
枫叶文学网www.fywxw.com
第8 章 文件cāo作
·197·
CFile f( pFileNcom, CFile::modeCreate | CFile::modeWrite );
}
CATCH( CFileException, e )
{
//文件未找到
if( e->m_cause == CFileException::fileNotFound )
TRACE( "ERROR: File not found\n")
}
END_CATCH
8.2.6 管理cāo作
对文件的cāo作,除了打开文件并进行读写外,还可以进行删除、重命名等cāo作。CFile
类也为这些cāo作提供了支持。
1.CFile::GetFilePath()
该函数用于获取指定文件的全路径。例如当CFile 打开了c:\aaa\bbb.dat 文件,调用
GetFilePath()就可以获得该文件的路径c:\aaa\bbb.dat。其原型为:
virtual CString GetFilePath() const;
函数返回值即为指定文件的完整路径。
2.CFile::GetFileTitle()
该函数用于获取指定文件的标题。例如当CFile 打开了c:\aaa\bbb.dat 文件,调用
GetFileTitle()就可以获得该文件的标题bbb。其原型为:
virtual CString GetFileTitle() const;
函数返回值即为指定文件的标题。
3.CFile::GetFileNcom()
该函数用于获取指定文件的名字。例如当CFile 打开了c:\aaa\bbb.dat 文件,调用
GetFileNcom()就可以获得该文件的名字bbb.dat。其原型为:
virtual CString GetFileNcom() const;
函数返回值即为指定文件的名字。
4.CFile::SetFilePath()
该函数用于设置文件的路径。该函数在下面的情况中使用,即当一个CFile 对象创建时
没有指定文件的路径。注意该函数并不能修改文件的实际路径,也不打开或创建新的文件。
其原型为:
virtual void SetFilePath(
LPCTSTR lpszNewNcom
);
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·198·
参数lpszNewNcom 用于指向新路径的字符串。
示例代码如下:
//用第二个构造函数创建一个与已经打开的文件句柄hFile 绑定的CFile 对象
CFile myFile((int) hFile);
//此时虽然myFile 已经通过hFile 获得了打开文件的句柄,但是它并不知道hFile 的文件名,
//因为hFile 并不包含文件名的信息。
//如果没有设置好与其关联的文件名,则异常对象CFileException::m_strFileNcom 将没有定义,
//无法获得出错的文件名。因此需要用SetFilePath 设置文件路径名。这里使用pstrNcom 指定。
myFile.SetFilePath(pstrNcom);
5.CFile::GetStatus()
该函数用于获得文件的状态,有两个不同的原型:非静态成员变量的原型、静态成员变
量的原型。
BOOL GetStatus(
CFileStatus& rStatus
) const;
static BOOL PASCAL GetStatus(
LPCTSTR lpszFileNcom,
CFileStatus& rStatus
);
前一个非静态成员函数用于获得CFile 打开的文件的状态,而后一个静态成员函数用于
获得指定文件的文件状态。
? 参数rStatus:CFileStatus 结构,用于获得文件状态。CFileStatus 结构如表8-3 所示。
? 参数lpszFileNcom:用于向静态成员函数提供要获取的文件名,可以是相对的路径也
可以是绝对路径。
? 函数返回值:确定获取是否成功。
注意,GetStatus()的非静态版本获取与CFile 对象有关的文件状态,不把值写入
CFileStatus::m_szFullNcom 结构成员中。而GetStatus()的静态版本用于获取文件的状态,同时
将文件名复制到CFileStatus::m_szFullNcom 中。此文件从目录项中获取文件状态而不打开文
件,这对于测试文件的存在xìng和访问权限十分有用。
表8-3 CFileStatus 结构说明
成员定义 成员说明
CTcom m_ctcom 文件创建的日期和时间
CTcom m_mtcom 文件最后修改的日期和时间
CTcom m_atcom 文件最后读取的日期和时间
LONG m_size 文件的逻辑字节长度
BYTE m_attribute 文件的属xìng字节状态
Char m_szFullNcom[_Max_PATH] 以Windows 字符集出现的绝对的文件名
CFileStatus::m_attribute 代表文件属xìng,MFC 在CFile 类中提供一个enum 类型用于以符
枫叶文学网www.fywxw.com
第8 章 文件cāo作
·199·
号的形式指定属xìng,具体代码如下:
enum Attribute {
normal = 0x00, //普通文件
readOnly = 0x01, //只读文件
hidden = 0x02, //隐藏文件
system = 0x04, //系统文件
volcom = 0x08, //分区文件
directory = 0x10, //目录文件
archive = 0x20 //存档文件
};
函数示例如下:
CFileStatus status; //文件状态变量
extern CFile cfile;
if( cfile.GetStatus( status ) ) // virtualcommber function
{
TRACE("File size = %ul\n", status.m_size);
}
char* pFileNcom = "test.dat"; //文件名
if( CFile::GetStatus( pFileNcom, status ) ) // 调用静态成员函数
{
TRACE("File ncom = %s\n", status.m_szFullNcom);
}
6.CFile:SetStatus()
该函数用于设置文件的状态,只有静态版本。其原型为:
static void PASCAL SetStatus(
LPCTSTR lpszFileNcom,
const CFileStatus& status
);
? 参数lpszFileNcom:指定要设置文件状态的文件名,可以是相对也可以是绝对路径。
? 参数status:确定要设置的新的文件状态,该参数是CFileStatus 结构类型,具体内容
见CFile::GetFileStatus()的介绍。一般情况下需要先获取原来的状态,再进行修改,否
则会造成一些需要保留的状态被修改。
函数示例如下:
char* pFileNcom = "test.dat"; //需要修改的文件名
CFileStatus status; //文件状态变量
CFile::GetStatus( pFileNcom, status ); //获取旧的文件状态
status.m_attribute |= CFile::readOnly; //添加只读属xìng
CFile::SetStatus( pFileNcom, status ); //设置新的属xìng
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·200·
7.CFile:Rencom()
该函数用于更改文件名,是CFile 的静态成员函数。其原型为:
static void PASCAL Rencom(
LPCTSTR lpszOldNcom,
LPCTSTR lpszNewNcom
);
? 参数lpszOldNcom:指定文件原来的路径名。
? 参数lpszNewNcom:指定文件新的路径名。
注意,该函数不能改变目录的名字。
8.CFile:Remove()
该函数用于删除指定的文件,也是一个静态成员函数。其原型为:
static void PASCAL Remove(
LPCTSTR lpszFileNcom
);
参数lpszOld
松语文学免费小说阅读_www.16sy.com
打开、读写、定位还是关闭cāo作都会产生异常。异常通常是由调用的函数抛出,在TRY/CATCH
块中捕获,此外CFile::Open()函数还可以用参数的形式获得异常的指针。
MFC 中文件的异常类是CFileException。CFileException 对象可以获得文件cāo作失败的原
因代码。该对象在CFile 成员函数中被创建和产生,也可以在CFile 派生类的成员函数中创建
和产生。程序用CATCH 表达式获取这一对象。CFileException 类包含可移植的原因代码和cāo
作系统制定的错误值的公共成员变量。一般情况下使用可移植的原因代码以实现平台的无关
xìng。
下面对CFileException 相关cāo作进行介绍,包括如何创建、抛出和获得异常。
1.创建并抛出异常
MFC 不允许手动创建CFileException 对象,而采用AfxThrowFileException()函数创建并
抛出文件异常。AfxThrowFileException()函数的原型为:
void AfxThrowFileException(
int cause,
LONG lOsError = -1,
LPCTSTR lpszFileNcom = NULL
);
? 参数cause:指定异常的原因,是一个枚举类型,具体枚举值如表8-2 所示。
? 参数lOsError:指定一个跟cāo作系统相关的异常原因。注意该值需要程序自行提供,
cāo作系统并不自动设置该值。
? 参数lpszFileNcom:指定出错的文件名。
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·196·
表8-2 文件异常原因代码
cause 取值 取值说明
CFileException::none 没有错误发生
CFileException::generic 一个没有特定意义的错误发生
CFileException::fileNotFound 无法找到文件
CFileExceptionLLbadPath 路径错误
CFileException::tooManyOpenFiles 超出允许的打开文件的最大数目
CFileException::accessDenied 文件无法访问
CFileException::invalidFile 尝试使用一个无效的文件句柄
CFileException::removeCurrentDir 当前工作目录无法被删除
CFileException::directoryFull 没有更多的目录项
CFileException::badSeek 移动文件指针错误
CFileException::hardIO 硬件错误
CFileException::sharingViolation 共享错误
CFileException::lockViolation 锁定错误
CFileException::diskFull 磁盘已满
CFileException::endOfFile 到达文件末尾
用户可以在自定义函数中添加自定义语句AfxThrowFileException 以抛出自定义的文件
异常,例如有一个CSampleFile 类用于指定存取一个有最大长度的文件,这个最大长度设置
为m_dwMaxLength,如果超出这个长度,就存取失败。下面给出一个写文件的例子,如果写
入的数据使得文件长度超出m_dwMaxLength,则模拟磁盘满的出错异常。
//向文件中写入字符串lpszString
void CSampleFile::WriteString(LPCTSTR lpszString)
{
//m_File 是CSampleFile 的成员变量
DWORD dwLen=m_File.GetLength()+strlen(lpszString)+1;//获得写入后的文件大小
if (dwLen>m_dwMaxLength)
AfxThrowFileException(CFileException::diskFull); //抛出磁盘满的异常
m_File.Write(lpszString,strlen(lpszString)+1); //如果没超过限度,则写入文件
}
2.获得文件异常信息
从第1 部分创建CFileException 异常中可以看出,文件异常有3 类不同的信息,分别由
3 个成员变量表示。
? CFileException::m_cause : int 类型, 获得可移植的出错代码, 这些代码同前面
AfxThrowFileException()函数的参数cause 的代码相同。
? CFileException::m_lOsError:long 类型,获得cāo作系统指定的出错代码。
? CFileException::m_strFileNcom:CString 类型,获得出错的文件名。
下面给出用TRY/CATCH 块获得文件异常信息的示例代码:
TRY
{
//创建文件进行写入
枫叶文学网www.fywxw.com
第8 章 文件cāo作
·197·
CFile f( pFileNcom, CFile::modeCreate | CFile::modeWrite );
}
CATCH( CFileException, e )
{
//文件未找到
if( e->m_cause == CFileException::fileNotFound )
TRACE( "ERROR: File not found\n")
}
END_CATCH
8.2.6 管理cāo作
对文件的cāo作,除了打开文件并进行读写外,还可以进行删除、重命名等cāo作。CFile
类也为这些cāo作提供了支持。
1.CFile::GetFilePath()
该函数用于获取指定文件的全路径。例如当CFile 打开了c:\aaa\bbb.dat 文件,调用
GetFilePath()就可以获得该文件的路径c:\aaa\bbb.dat。其原型为:
virtual CString GetFilePath() const;
函数返回值即为指定文件的完整路径。
2.CFile::GetFileTitle()
该函数用于获取指定文件的标题。例如当CFile 打开了c:\aaa\bbb.dat 文件,调用
GetFileTitle()就可以获得该文件的标题bbb。其原型为:
virtual CString GetFileTitle() const;
函数返回值即为指定文件的标题。
3.CFile::GetFileNcom()
该函数用于获取指定文件的名字。例如当CFile 打开了c:\aaa\bbb.dat 文件,调用
GetFileNcom()就可以获得该文件的名字bbb.dat。其原型为:
virtual CString GetFileNcom() const;
函数返回值即为指定文件的名字。
4.CFile::SetFilePath()
该函数用于设置文件的路径。该函数在下面的情况中使用,即当一个CFile 对象创建时
没有指定文件的路径。注意该函数并不能修改文件的实际路径,也不打开或创建新的文件。
其原型为:
virtual void SetFilePath(
LPCTSTR lpszNewNcom
);
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·198·
参数lpszNewNcom 用于指向新路径的字符串。
示例代码如下:
//用第二个构造函数创建一个与已经打开的文件句柄hFile 绑定的CFile 对象
CFile myFile((int) hFile);
//此时虽然myFile 已经通过hFile 获得了打开文件的句柄,但是它并不知道hFile 的文件名,
//因为hFile 并不包含文件名的信息。
//如果没有设置好与其关联的文件名,则异常对象CFileException::m_strFileNcom 将没有定义,
//无法获得出错的文件名。因此需要用SetFilePath 设置文件路径名。这里使用pstrNcom 指定。
myFile.SetFilePath(pstrNcom);
5.CFile::GetStatus()
该函数用于获得文件的状态,有两个不同的原型:非静态成员变量的原型、静态成员变
量的原型。
BOOL GetStatus(
CFileStatus& rStatus
) const;
static BOOL PASCAL GetStatus(
LPCTSTR lpszFileNcom,
CFileStatus& rStatus
);
前一个非静态成员函数用于获得CFile 打开的文件的状态,而后一个静态成员函数用于
获得指定文件的文件状态。
? 参数rStatus:CFileStatus 结构,用于获得文件状态。CFileStatus 结构如表8-3 所示。
? 参数lpszFileNcom:用于向静态成员函数提供要获取的文件名,可以是相对的路径也
可以是绝对路径。
? 函数返回值:确定获取是否成功。
注意,GetStatus()的非静态版本获取与CFile 对象有关的文件状态,不把值写入
CFileStatus::m_szFullNcom 结构成员中。而GetStatus()的静态版本用于获取文件的状态,同时
将文件名复制到CFileStatus::m_szFullNcom 中。此文件从目录项中获取文件状态而不打开文
件,这对于测试文件的存在xìng和访问权限十分有用。
表8-3 CFileStatus 结构说明
成员定义 成员说明
CTcom m_ctcom 文件创建的日期和时间
CTcom m_mtcom 文件最后修改的日期和时间
CTcom m_atcom 文件最后读取的日期和时间
LONG m_size 文件的逻辑字节长度
BYTE m_attribute 文件的属xìng字节状态
Char m_szFullNcom[_Max_PATH] 以Windows 字符集出现的绝对的文件名
CFileStatus::m_attribute 代表文件属xìng,MFC 在CFile 类中提供一个enum 类型用于以符
枫叶文学网www.fywxw.com
第8 章 文件cāo作
·199·
号的形式指定属xìng,具体代码如下:
enum Attribute {
normal = 0x00, //普通文件
readOnly = 0x01, //只读文件
hidden = 0x02, //隐藏文件
system = 0x04, //系统文件
volcom = 0x08, //分区文件
directory = 0x10, //目录文件
archive = 0x20 //存档文件
};
函数示例如下:
CFileStatus status; //文件状态变量
extern CFile cfile;
if( cfile.GetStatus( status ) ) // virtualcommber function
{
TRACE("File size = %ul\n", status.m_size);
}
char* pFileNcom = "test.dat"; //文件名
if( CFile::GetStatus( pFileNcom, status ) ) // 调用静态成员函数
{
TRACE("File ncom = %s\n", status.m_szFullNcom);
}
6.CFile:SetStatus()
该函数用于设置文件的状态,只有静态版本。其原型为:
static void PASCAL SetStatus(
LPCTSTR lpszFileNcom,
const CFileStatus& status
);
? 参数lpszFileNcom:指定要设置文件状态的文件名,可以是相对也可以是绝对路径。
? 参数status:确定要设置的新的文件状态,该参数是CFileStatus 结构类型,具体内容
见CFile::GetFileStatus()的介绍。一般情况下需要先获取原来的状态,再进行修改,否
则会造成一些需要保留的状态被修改。
函数示例如下:
char* pFileNcom = "test.dat"; //需要修改的文件名
CFileStatus status; //文件状态变量
CFile::GetStatus( pFileNcom, status ); //获取旧的文件状态
status.m_attribute |= CFile::readOnly; //添加只读属xìng
CFile::SetStatus( pFileNcom, status ); //设置新的属xìng
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·200·
7.CFile:Rencom()
该函数用于更改文件名,是CFile 的静态成员函数。其原型为:
static void PASCAL Rencom(
LPCTSTR lpszOldNcom,
LPCTSTR lpszNewNcom
);
? 参数lpszOldNcom:指定文件原来的路径名。
? 参数lpszNewNcom:指定文件新的路径名。
注意,该函数不能改变目录的名字。
8.CFile:Remove()
该函数用于删除指定的文件,也是一个静态成员函数。其原型为:
static void PASCAL Remove(
LPCTSTR lpszFileNcom
);
参数lpszOld
松语文学免费小说阅读_www.16sy.com