CFile

  文件处理是程序中的一个重头戏,主要用到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 }
View Code
 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 直接构造去创建一个新的文件如果这个文件存在,则删除这个文件里所有内容

   CFile::modeNoTruncate 联合创建属性,如果这个文件已创建,则不删除原文件内容,因而这个文件是可以当做一个已经存在,或者不存在而被新建的文件来保证打开。这是非常有意义的,例如,打开来设置一个存在或者不存在的文件都是可以的。这个属性对于CStdioFile也是非常好的
   CFile::modeRead 打开为只读属性.
   CFile::modeWrite 打开为只写属性.
   CFile::modeReadWrite 打开为读写属性.
   CFile::modeNoInherit 防止这个文件来源于子进程.
   CFile::shareDenyNone 在这个文件读写处理之外打开这个文件
   CFile::shareDenyRead 以独占方式打开,拒绝其他读操作
   CFile::shareDenyWrite 以独占方式打开,拒绝其他写操作
   CFile::shareExclusive 以独占方式打开文件,拒绝其他读写操作访问这个文件Opens the file with exclusive mode, denying other 如果这个文件已打开进行读写操作则构造失败
   CFile::shareCompat 这个属性在 32 bit MFC是不可用的. This flag maps to CFile::shareExclusive 当应用在CFile::Open.
   CFile::typeText 设置文本模式特别处理回车换行 (used in derived classes only).
   CFile::typeBinary 设置二进制模式(used in derived classes only).

 

 大家常用的从文件中读写字符串的类CStdioFile就是从CFile派生出的,因此CStdioFile类的对象也可以直接调用Open方法来打开一个对象,参看以下例子:

   CString csExt;
   CStdioFile Rfile(_T("C:\\myfiles\\myfile1.txt"),CFile::modeRead); //定义并初始化一个CStdioFile类的对Rfile
   //一行一行的读入字符串
   while(Rfile.ReadString(csExt))
   {
   TRACE(_T("%s\n"),csExt);
   }
   Rfile.Close();
 
读文件:
virtual UINT Read(
   void* lpBuf,
   UINT nCount 
);
lpBuf:
用户指定的要存储所读的内容的缓冲区指针
nCount:指定要读写的最大字节数
返回实际读的字节数 当遇到EOF时,小于nCount
EX(MSDN):
View Code
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:指向要写入的数据的缓冲区
nCount:要写入的字节数
无返回值。
EX(MSDN):
View Code
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):

View Code
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
} 

 

posted on 2012-04-23 10:00  傻瓜乐园  阅读(2291)  评论(0编辑  收藏  举报

导航