居长而行三:VC文件操作--世界中的电子圣灵

来源:百度文库 编辑:中财网 时间:2024/04/29 10:48:14
一、FILE
FILE*fopen (const char *filemane,const char *mode);
打开文件filemane返回相联系的流;出错返回NULL。
mode字符串的可取值有:r,打开用于读;w,打开用于写;a,打开用于在原有内容之后写;r+,打开已存在的文件用于更新(读和写);w+创建新文件用于更新;a+,打开用于在原有内容之后更新,若文件不存在就创建。
头文件:#include
unsigned char oldchar[0xedd00] ;
FILE *fr =fopen("HK-M30G字库.bin", "rb" );
fread(oldchar, 0xedd00, 1, fr);
fclose(fr);
FILE *stream = fopen("NewFile.bin", "wb+" );   // 以创建方式打开文件
fwrite(oldchar, sizeof(oldchar), 1, stream);
fread();
fclose(stream);     // 关闭文件指针
二:CFile类
1、文件打开函数Open
BOOL Open(LPCTSTR lpszFileName,  UINT nOpenFlags,    CFileException* pError = NULL);
参数lpszFileName:为欲打开的文件名,文件名可以包含路径和文件名两部分。如“d:\\bak\\test.txt”, 如果此字符串不包含文件路径,如“test.bak”,则系统默认为当前路径,即生成的可执行文件所在目录。
参数nOpenFlags:用于设置访问模式,指定当打开文件时进行的动作,可以将以下所列模式用按位或“|”操作符连接起来。至少应有一个访问模式,modeCreate是可选的。以下是常用参数列表:
CFile::modeCreate:调用构造函数构造一个新文件。
CFile::modeRead :       打开文件仅供读。
CFile::modeReadWrite:        打开文件供读/写。
CFile::modeWrite:        打开文件仅供写。
CFile::typeText:    设置文本文件模式(只能用在子类中)。
CFile::typeBinary:设置二进制文件模式(只能用在子类中)。
参数 pError:是一个异常类的指针,可通过该类和函数的返回值来确定函数是否调用成功,如下表所示。
Perror
返回值
调用是否成功
异常类的设置
NULL
True
Y
NULL
False
N
CFileException
True
Y
没有变化
CFileException
False
N
置入错误信息
注意:参数 pError为CFileException类型。而CFileException是异常类的一种,用于检测文件操作中可能出现的错误
例如:
CFile       f;
if (!f.Open(“D:\\bak\\test.txt”, CFile::modeCreate | CFile::modeWrite))
return false;
2、用于打开文件的构造函数
CFile(LPCTSTR lpszFileName, UINT nOpenFlags) throw( CFileException );
如:
CFile f(“D:\\bak\\test.txt”, Cfile::modeRead);
注意:构造函数没有返回值,当打开文件出错时只是产生一个异常。所以不能象函数那样通过分支语句来保证文件已打开,而应使用TRY/CATCH宏来判断。
例:
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 :          到达文件结尾。
3、成员函数Close
定义:void Close();
Close函数用于关闭由Open函数打开的文件。使用Open函数打开文件后,应使用Close函数释放文件句柄及缓冲区的资源。
打开文件和关闭文件的例子。
CFile       f;
if  (!f.Open(“D:\\bak\test.txt”, CFile::modeRead))
{
MessageBox(“打开文件失败!”);
return ;
}
f.Close();
4、读写函数
virtual UINT Read (void* lpBuf,  UINT nCount) ;  throw(CFileException);
Read函数返回值是传输到缓冲区的字节数。
参数lpBuf:指向用户提供的缓冲区以接收从文件中读取的数据。
参数nCount:为可以从文件中读出字节数的最大值。
注意:对所有CFile类,如果到达文件尾,则返回值可能比nCount小。
virtual void Write(const void* lpBuf, UINT nCount);    throw (CFileException);
Write函数的参数与Read函数的参数类似。
参数lpBuf:指向用户提供的缓冲区,包含将写入文件中的数据。
参数nCount:从缓冲区内传输的字节数。
Write在几种情况下均产生异常,包括磁盘满的情况、磁盘为写保护状态等。
注意:CFile类并没有提供类似EOF之类的文件结束标志,所以文件的结束是根据Read函数的返回值来判断的。Read函数返回的是实际读出的字符数,当返回0时,则表示文件已读完。
例1:文件复制
BOOL Copy(CString strSource, CString strTarget)
{
CFile fSource, fTarget;
char c[4096];     //定义4k字节的缓冲区
nt    nCount;
//打开文件
if  (!fSource.Open(strSource, CFile::modeRead))
{
MessageBox(“Open Source File Fail!”);
return  false;
}
if  (!fTarget.Open(strTarget, CFile::modeCreate | CFile::modeWrite))
{
MessageBox(“Create Target File Fail!”);
fSource.Close();
return  false;
}
//读文件到缓冲区c
nCount = fSource.Read(c, 4096);
while (nCount)
{
fTarget.Write(c, nCount);
nCount = fSource.Read(c, 4096);
}
fSource.Close();
fTarget.Close();
}
例2:文件复制
struct tegStudent
{
int nCode;
char sName[10];
int nAge;
} STUDENT, * LPSTUDENT;
BOOL Copy(CString strSource, CString strTarget)
{
CFile fSource, fTarget;
//定义STUDENT变量
STUDENT  s;
int       nCount;
//打开文件
if  (!fSource.Open(strSource, CFile::modeRead))
{
MessageBox(“Open Source File Fail!”);
return  false;
}
if  (!fTarget.Open(strTarget, CFile::modeCreate | CFile::modeWrite))
{
MessageBox(“Create Target File Fail!”);
fSource.Close();
return  false;
}
//读文件到缓冲区c
nCount = fSource.Read(s, sizeof(STUDENT));
while (nCount)
{
fTarget.Write(s, sizeof(STUDENT));
nCount = fSource.Read(s, sizeof(STUDENT));
}
fSource.Close();
fTarget.Close();
}
5、文件的定位
(1) virtual LONG Seek(LONG lOff, UINT nFrom); throw(CFileException);
返回值:如果要求的位置合法,则Seek返回从文件开始的字节偏移量。否则值未定义,并产生CFileException异常。
参数lOff:指针移动的字节数。
参数nFrom:指针移动的参照点,有三种取值如下:
CFile::begin:从文件开始,把指针向后移动lOff字节。
CFile::current:从当前位置开始,把指针向后移动lOff字节。
CFile::end:从文件尾开始,把指针向后移动lOff字节。
例:
CFile f;
LONG lOffset = 1000, lActual;
lActual = cfile.Seek(lOffset,CFile::begin);
(2) void SeekToBegin( ); throw(CFileException);
函数SeekToBegin将文件指针指向文件开始处。
(3) DWORD SeekToEnd( ); throw( CFileException );
函数SeekToEnd将文件指针指向文件逻辑尾部,返回值为文件长度(字节数)
例:假设f为已打开文件,且以STUDENT结构(定义见上例)为记录,下面的GetData函数读取第nRecord条记录的值。
例1:
STUDENT GetData(CFile  f,  int nRecord)
{
int           offset;
STUDENT     s;
//计算第nRecord条记录在文件中的位置
offset = (nRecord – 1) * sizeof(STUDENT);
//文件指针移到文件头
f.SeekToBegin();
//从当前位置移动offset个字节
f.Seek(offset, CFile::current);
//读取记录信息
f.Read(s, sizeof(STUDENT));
return s;
}
(4) virual DWORD GetPosition()const ;throw(CFileException);
该函数返回一个32位的无符号整型数,用于标识当前文件指针相对于文件头的偏移量。
例:使用该函数求文件的长度。
DWORD GetFileLength(CFile f)
{
f.SeekToEnd();
return f.GetPosition();
}
6、文件的状态函数
(1) virtual DWORD GetLength() const; throws (CFileException);
该函数没有参数,直接返回文件以字节计的长度。
(2) GetFileName():   取得文件名
(3) GetFileTitle():  取得文件标签
(4) GetFilePath():   取得文件路径
(5) BOOL GetStatus(CFileStatus  & rStatus) const;
如果指定文件的状态信息成功获取,该函数的返回值为TRUE,否则为FALSE。
参数rStatus:用于返回文件的信息。这里使用了CFileStatus结构来接收状态信息。以下是CFileStatus结构的定义:
stuct CFileStatus
{
CTime  m_ctime;       //文件创建的时间
CTime  m_mtime;     //文件最后一次修改的时间
CTime m_atime;       //最后一次访问文件并读取的时间
LONG m_size;          //文件逻辑长度,以字节数表示
BYTE m_attribute;             //文件属性字节
// Windows字符集表示的全文件名
TCHAR m_szFullName[MAX_PATH];
};
m_attribute成员表述文件属性 ,MFC提供一个enum类型的属性 ,如下:
enum Attribute
{
normal=0x00,                              // 一般
readOnly=0x01,                       // 只读
hidden=0x02,           // 隐藏
system=0x04,                       // 系统
volume=0x08,                         //  卷标
directory=0x10,                        // 目录
archive=0x20                             // 归档
};
例:
BOOL IsReadOnly(CFile f)
{
CFileStatus     fs;
//注意:函数的参数为引用不是指针,所以不需要用取地址符号
f.GetStatus(fs);
if (fs. m_attribute & CFile:: readOnly ==  fs. m_attribute)
return true;
else
return false;
}
7、CFile类的静态函数
(1) GetStatus与SetStatus函数
GetStatus(),用于取得指定文件的状态信息
Static BOOL PASCAL GetStatus(LPCSTR lpszFileName, CFileStatus & rStatus);
参数LpszFileName:文件路径, 可为绝对路径或为相对路径。
参数rStatus:用于返回文件的信息。
SetStatus(),用于设置指定文件的状态信息。
Static BOOL PASCAL SetStatus(LPCSTR lpszFileName, const CFileStatus & rStatus);
例:设置文件为只读
void SetReadOnly(CString strFilename)
{
CFileStatus     fs;
CFile::GetStatus(strFilename, fs);
fs. m_attribute  |=  CFile:: readOnly;
CFile::SetStatus(strFilename, fs);
}
(2)函数Remove()
函数Remove()用于删除指定的文件。
static void PASCAL Remove(LPCTSTR lpszFileName); throw(CFileException);
参数lpszFileName:表示所要删除文件的路径字符串。路径可为相对或绝对。
说明此静态函数删除由路径指定的文件,但不可移去一个目录。如果相关联的文件打开或文件不可移去,则函数产生一个异常。这个函数等价于DOS中的del命令。
例:删除文件
CString  strFileName =″d:\\bak\\test.dat″;
CFile::Remove(strFileName);
(3)函数Rename()
函数Rename()用于更改指定文件的文件名。
static void PASCAL Rename(LPCTSTR lpszOldName, LPCTSTR lpszNewName);
throw (CFleException);
参数lpszOldName原路径。
lpszNewName新路径。此函数用于改名一个指定文件。注意目录不可改变,这个函数等价于DOS中的REN命令。
例:更改文件名
CString strSource = “d:\\bak\\test.txt”;
CString strTarget = “d:\\bak\\test1.txt”;
CFile::Rename(strSource, strTarget);