文件处理是程序中的一个重头戏,主要用到CFile和CArchive及他们的派生类。
CFile:
It directly provides unbuffered, binary disk input/output services, and it indirectly supports text files and memory files through its derived classes. CFile works in conjunction with the CArchive class to support serialization of Microsoft Foundation Class objects.
用于非缓存 二进制磁盘 输入输出设备 其派生类可用于文本文件和内存文件
Normally, a disk file is opened automatically on CFile construction and closed on destruction. Static member functions permit you to interrogate a file's status without opening the file.
硬盘文件可通过构造函数和析构函数自动打开或关闭 可以通过调用静态成员函数不打开文件就获取该文件的状态。
成员函数有:
CFlie() Open() Close() Read() Write() Flush() GetLength() Seek() SeekToBegin() SeekToEnd() GetLength()
GetFileName() GetFilePath() GetFileTitle() GetStatus() ReName()
打开:
构造函数打开:
CFile(
HANDLE hFile
);
CFile(
LPCTSTR lpszFileName,
UINT nOpenFlags
);
EX(MSDN):
1 HANDLE hFile = CreateFile(_T("CFile_File.dat"), 2 GENERIC_WRITE, FILE_SHARE_READ, 3 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 4 5 if (hFile == INVALID_HANDLE_VALUE) 6 { 7 AfxMessageBox(_T("Couldn't create the file!")); 8 } 9 else 10 { 11 // Attach a CFile object to the handle we have. 12 CFile myFile(hFile); 13 14 static const TCHAR sz[] = _T("I love CFile!"); 15 16 // write string 17 myFile.Write(sz, sizeof(sz)); 18 19 // We can call Close() explicitly, but the destructor would have 20 // also closed the file for us. Note that there's no need to 21 // call the CloseHandle() on the handle returned by the API because 22 // MFC will close it for us. 23 myFile.Close();
成员函数Open:
virtual BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL );
两步走:
1.创建一个用于打开文件的对象,通常都是声明一个CFile或者一个CFile派生类的对象。
2.调用该CFile对象的Open方法,并提供一个文件路径和打开方式作为Open方法的参数。
EX(MSDN上):
1 CFile f; 2 CFileException e; 3 TCHAR* pszFileName = _T("Open_File.dat"); 4 if(!f.Open(pszFileName, CFile::modeCreate | CFile::modeWrite, &e)) 5 { 6 TRACE(_T("File could not be opened %d\n"), e.m_cause); 7 }
1 //A second example for CFile::Open. 2 //This function uses CFile to copy binary files. 3 bool BinaryFileCopy(LPCTSTR pszSource, LPCTSTR pszDest) 4 { 5 // constructing these file objects doesn't open them 6 CFile sourceFile; 7 CFile destFile; 8 9 // we'll use a CFileException object to get error information 10 CFileException ex; 11 12 // open the source file for reading 13 if (!sourceFile.Open(pszSource, 14 CFile::modeRead | CFile::shareDenyWrite, &ex)) 15 { 16 // complain if an error happened 17 // no need to delete the ex object 18 19 TCHAR szError[1024]; 20 ex.GetErrorMessage(szError, 1024); 21 _tprintf_s(_T("Couldn't open source file: %1024s"), szError); 22 return false; 23 } 24 else 25 { 26 if (!destFile.Open(pszDest, CFile::modeWrite | 27 CFile::shareExclusive | CFile::modeCreate, &ex)) 28 { 29 TCHAR szError[1024]; 30 ex.GetErrorMessage(szError, 1024); 31 _tprintf_s(_T("Couldn't open source file: %1024s"), szError); 32 33 sourceFile.Close(); 34 return false; 35 } 36 37 BYTE buffer[4096]; 38 DWORD dwRead; 39 40 // Read in 4096-byte blocks, 41 // remember how many bytes were actually read, 42 // and try to write that many out. This loop ends 43 // when there are no more bytes to read. 44 do 45 { 46 dwRead = sourceFile.Read(buffer, 4096); 47 destFile.Write(buffer, dwRead); 48 } 49 while (dwRead > 0); 50 51 // Close both files 52 53 destFile.Close(); 54 sourceFile.Close(); 55 } 56 57 return true; 58 }
打开的共享和访问属性设置:
CFile::modeCreate 直接构造去创建一个新的文件如果这个文件存在,则删除这个文件里所有内容
大家常用的从文件中读写字符串的类CStdioFile就是从CFile派生出的,因此CStdioFile类的对象也可以直接调用Open方法来打开一个对象,参看以下例子:
virtual UINT Read( void* lpBuf, UINT nCount );nCount:指定要读写的最大字节数
lpBuf:用户指定的要存储所读的内容的缓冲区指针
CFile cfile; cfile.Open(_T("Write_File.dat"), CFile::modeCreate | CFile::modeReadWrite); char pbufWrite[100]; memset(pbufWrite, 'a', sizeof(pbufWrite)); cfile.Write(pbufWrite, 100); cfile.Flush(); cfile.SeekToBegin(); char pbufRead[100]; cfile.Read(pbufRead, sizeof(pbufRead)); ASSERT(0 == memcmp(pbufWrite, pbufRead, sizeof(pbufWrite)));
写文件: (最好使用try...catch...块来捕捉错误)
virtual void Write( const void* lpBuf, UINT nCount );lPBuf:指向要写入的数据的缓冲区
CFile cfile; cfile.Open(_T("Write_File.dat"), CFile::modeCreate | CFile::modeReadWrite); char pbufWrite[100]; memset(pbufWrite, 'a', sizeof(pbufWrite)); cfile.Write(pbufWrite, 100); cfile.Flush();
Flush()函数:
virtual void Flush( );
Forces any data remaining in the file buffer to be written to the file.
将文件缓冲区中的数据写进文件中,一般在调用write函数之后都要调用以下Flush函数
EX(MSDN):
TCHAR* pstrName = _T("C:\\test\\SetPath_File.dat"); // open a file HANDLE hFile = ::CreateFile(pstrName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); if (hFile != INVALID_HANDLE_VALUE) { // attach a CFile object to it CFile myFile(hFile); // At this point, myFile doesn't know the path name for the file // it owns because Windows doesn't associate that information // with the handle. Any CFileExceptions thrown by this object // won't have complete information. // Calling SetFilePath() remedies that problem by letting CFile // know the name of the file that's associated with the object. myFile.SetFilePath(pstrName); // write something to the file and flush it immediately DWORD dwValue = 1234; myFile.Write(&dwValue, sizeof(dwValue)); myFile.Flush(); // destroying the CObject here will call ::CloseHandle() on the file }