现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

MFC中文件操作、查找与选择总结(2)

2012-12-13 12:51 工业·编程 ⁄ 共 2909字 ⁄ 字号 暂无评论

(二)CArchive类操作
 
     CArchive类实现数据的缓冲区读写,同时定义了类对象的存储与读取方案。 在文档视图编程,结合CList和CArray等可很方便的实现数据读写。
 
     (1)基本数据读写----显示创建CArchive对象
 
     A.  使用CArhive类之前,必须要有一个CFile文件对象,同时必须保证CArchive的操作必须是在CFile处于打开状态,且操作期间文件状态不会发生变化。
 
     B. 然后定义CArchive对象,将其与CFile对象关联,并指定其模式是用于缓冲区读还是写:
 

      CArchive ar (pFile,             //目标文件,CFile对象指针
 
                              nMode,        //操作方式, 读/写
 
                              nBufSize,    //指定缓冲区大小,默认为4096
 

                              lpBuf           //缓冲指针,默认为NULL,即从本地堆中取出一块内存空间,操作结束后自动释放
 

                            );
 

      C.对于基本数据类型,可直接使用operator >>和operator <<进行数据读出和写入。这些数据类型BYTE、WORD、LONG、DWORD、float、double、int、short、char、unsigned u等。 对于CString对象也可使用。
 
       对于自定义的结构体数据类型,我们自己可以重载这两个运算符,一个示例如下。

01.typedef struct test_st 
02.{ 
03.     float valueX; 
04.     float valueY; 
05. 
06.     //重载<<和>>运算符 
07.    friend CArchive& AFXAPI operator <<(CArchive& ar, const test_st& info) 
08.  { 
09.        //保存 
10.       ar<<info.valueX<<info.valueY; 
11.       return ar; 
12.  } 
13.   friend CArchive& AFXAPI operator >>(CArchive& ar, test_st& info) 
14.   { 
15.        //读取 
16.        ar>>info.valueX>>info.valueY; 
17.        return ar; 
18.   } 
19.}TEST; 
 

     D. 使用Read和Write可实现指定数据长度的数据写入/读取,这里的数据长度指的是字节数。
 
         使用WriteString可写入字符串,ReadString可读出一行字符。注意这里WriteString并不是写入一行字符串,WriteString写入的字符串时不会写入'\0',也不会自动写入'\n'。下面是来自MSDN的一个例子,相信能说明问题。
01.CFile myFile("myfile", CFile::modeCreate | CFile::modeReadWrite); 
02.CString str1="String1", str2="String2", str; 
03. 
04.// Create a storing archive. 
05.CArchive arStore(&myFile, CArchive::store); 
06. 
07.// Write str1 and str2 to the archive 
08.arStore.WriteString( str1 ); 
09.arStore.WriteString( "\n" ); 
10.arStore.WriteString( str2 ); 
11.arStore.WriteString( "\n" ); 
12. 
13.// Close the storing archive 
14.arStore.Close(); 
15. 
16.// Create a loading archive. 
17.myFile.SeekToBegin(); 
18.CArchive arLoad(&myFile, CArchive::load); 
19. 
20.// Verify the two strings are in the archive. 
21.arLoad.ReadString( str ); 
22.ASSERT( str == str1 ); 
23.arLoad.ReadString( str ); 
24.ASSERT( str == str2 ); 
 

      E. IsLoading 和 IsStoring函数常用来判断是读取还是写入。
 
          Close函数用于切断与CFile对象的关联,在这之前会自动调用Flush将缓冲区数据写入存储媒质中。
 
     F. 在程序中,如果没有调用函数Flush(),那么真正将数据写入到物理磁盘是在调用函数Close()关闭时。因此,一些重要的数据需要使用Flush()函数立即写入文件,以防丢失。
 

      (2)类对象的读写
 

       A. 利用CArchive保存/加载一个类对象,则此类必须支持串行化。
 
      B. 自定义串行化类的五个步骤:
 
          ①继承CObject类;
 
          ②重载CObject类的Serialize成员函数;
 
          ③在类的.h文件中,进行串行化的声明:DECLARE_SERIAL(类名);
 
          ④定义一个无参数的构造函数;
 
          ⑤在类的.cpp文件中,进行声明:IMPLEMENT_SERIAL(类名, CObject, 版本号)
 
      C. 在自定义的类的Serialize成员函数下,使用上述(1)中的方法,保存/加载基本数据类型。如下。在需要文件操作的地方,直接调用该函数即可。

01.void CXXXX::Serialize(CArchive &ar) 
02.{ 
03.     if (ar.IsStoring()) 
04.     {    //保存 
05.          //Add code.... 
06.     } 
07.     else 
08.     {   //读取 
09. 
10.        //Add code... 
11.     } 
12.} 
 

       D. 利用此方法,可实现数据的分布式保存。通常在文档视图编程时,我们在文档类下定义数据对象,然后在其Serialize函数下实现数据的保存/加载即可。
 
通常我们会定义一个容器,用来存放数据。例如,在我的项目中,我使用了
 
CTypedPtrList<CObList, CObject*> m_DataList;
 
这是一个链表,里面元素为CObject类对象的指针,当我们自定义了支持串行化的类后,就可以把数据加入到这个链表中,很方便的实现数据管理和存储。

给我留言

留言无头像?