文件操作系列之六——(CArchive的文件操作)

下面介绍一种特殊的文件操作方式——CArchive。

CArchive 的介绍:

Allows you to save a complex network of objects in a permanent binary form (usually disk storage) that persists after those objects are deleted.

CArchive does not have a base class.

Later you can load the objects from persistent storage, reconstituting them in memory. This process of making data persistent is called "serialization."

从这些话中我们可以得知,CArchive使用了缓冲区,即一段内存空间作为临时数据存储地,对CArchive的读写都先依次排列到此缓冲区,当缓冲区满或用户要求时,将此段整 理后的数据读写到指定的存储煤质。 当建立CArchive对象时,应指定其模式是用于缓冲区读,还是用于缓冲区写。

一般情况下创建 CArchive 对象有两种方法:

  • 通过框架隐式创建 CArchive 对象
  • 显式创建 CArchive 对象

一. 通过框架隐式创建 CArchive 对象

最普通且最容易的方法是使框架代表“文件”菜单上的“保存”、“另存为”和“打开”命令为文档创建 CArchive 对象。

以下是应用程序的用户从“文件”菜单上发出“另存为”命令时,框架所执行的操作:

  1. 显示“另存为”对话框并从用户获取文件名。
  2. 打开用户命名的文件作为 CFile 对象。
  3. 创建指向该 CFile 对象的 CArchive 对象。在创建 CArchive 对象时,框架将模式设置为“存储”(即写入或序列化),而不是“加载”(即读取或反序列化)。
  4. 调用在 CDocument 派生类中定义的 Serialize 函数,将 CArchive 对象的引用传递给该函数。

然后,文档的 Serialize 函数将数据写入 CArchive 对象(刚作了解释)。从 Serialize 函数返回时,框架先销毁 CArchive 对象,再销毁 CFile 对象。

因此,如果让框架为文档创建 CArchive 对象,您所要做的一切是实现写入存档和从存档中读取的文档的 Serialize 函数。您还必须为文档的 Serialize 函数直接或间接依次序列化的任何 CObject 派生对象实现 Serialize。 显 式创建 CArchive 对象

除了通过框架将文档序列化之外,在其他场合也可能需要 CArchive 对象。例如,可能要序列化到达或来自剪贴板的数据,由 CSharedFile 对象表示。或者,可能要使用用户界面来保存与框架提供的文件不同的文件。在这种情况下,可以显式创建 CArchive 对象。使用下列过程,用与框架采用的相同方式来执行此操作。

二. 显式创建 CArchive 对象

  1. 构造 CFile 对象或从 CFile 导出的对象。
  2. 按照下面示例所示,将 CFile 对象传递到 CArchive 的构造函数:
    CFile theFile;
    theFile.Open(..., CFile::modeWrite);
    CArchive archive(&theFile, CArchive::store);

CArchive 构造函数的第二个参数是指定存档将用于向文件中存储数据还是用于从文件中加载数据的枚举值。对象的 Serialize 函数通过调用存档对象的 IsStoring 函数来检查该状态。

当完成向 CArchive 对象存储数据或从该对象中加载数据时,关闭该对象。虽然 CArchive 对象(和 CFile 对象)会自动关闭存档(和文件),好的做法是显式执行,因为这使从错误恢复更为容易。

最后关闭 CArchive 对象

archive.Close();

theFile.Close();

下面使用一个简单示例来说明:

读文件:

char filename[50]; cout<<"Pleast input the file name you want to Read:/n"; cin>>filename; WCHAR wszfileName[256]; // Unicode user name // Convert ANSI filename to Unicode MultiByteToWideChar( CP_ACP, 0, filename, strlen(filename)+1, wszfileName, sizeof(wszfileName)/sizeof(wszfileName[0]) ); CFile myFile(wszfileName, CFile::modeRead); CArchive ar(&myFile, CArchive::load); //注意选择合适的方式,load为读 int n; float f; CString str; if (ar.IsLoading()) { //通过>>来读取,顺序必须和写入顺序相同 ar>>n>>f>>str; cout<<n<<endl; cout<<f<<endl; wcout<<(LPCTSTR)str<<endl; //read char readBuf[100]; ar.Read(readBuf, 100); cout<<readBuf; //readstring ar.ReadString(str); wcout<<(LPCTSTR)str<<endl; ar.ReadString(str); wcout<<(LPCTSTR)str<<endl; } ar.Close(); myFile.Close();

写文件:

cout<<"Pleast input the file name you want to Write:/n"; char filename[50]; cin>>filename; WCHAR wszfileName[256]; // Unicode user name // Convert ANSI filename to Unicode MultiByteToWideChar( CP_ACP, 0, filename, strlen(filename)+1, wszfileName, sizeof(wszfileName)/sizeof(wszfileName[0]) ); CFile myFile(wszfileName, CFile::modeCreate | CFile::modeReadWrite); CArchive ar(&myFile, CArchive::store); //注意选择合适的方式,store为写 int n = 10; float f = 2.4f; CString str("Hello CArchive!"); CString str1("String1"), str2("String2"); char writeBuf[100] = "Write Character!/n"; if (ar.IsStoring()) { //通过<<写入 ar<<n<<f<<str; //Write ar.Write(writeBuf, 100); // Write str1 and str2 to the archive ar.WriteString(str1); ar.WriteString(_T("/n")); ar.WriteString(str2); ar.WriteString(_T("/n")); } ar.Close(); myFile.Close();

除此之外,CArchive还可以写如类对象等数据。我们可以通过WriteClass(),WriteObject()和起配套的ReadClass(),ReadObject()来进行读写。如下面的例子:

WriteClass()/ReadClass():

CFile myFile(_T("Myfile.dat"), CFile::modeCreate | CFile::modeReadWrite); // Create a storing archive. CArchive arStore(&myFile, CArchive::store); // Store the class CAge in the archive. arStore.WriteClass(RUNTIME_CLASS(CAge)); // Close the storing archive. arStore.Close(); // Create a loading archive. myFile.SeekToBegin(); CArchive arLoad(&myFile, CArchive::load); // Load a class from the archive. CRuntimeClass* pClass = arLoad.ReadClass(); if (!pClass->IsDerivedFrom(RUNTIME_CLASS(CAge))) { arLoad.Abort(); }

WriteObject()/ReadObject():

CFile myFile(_T("Myfile.dat"), CFile::modeCreate | CFile::modeReadWrite); CAge age(21), *pAge; // Create a storing archive. CArchive arStore(&myFile, CArchive::store); // Write the object to the archive arStore.WriteObject(&age); // Close the storing archive arStore.Close(); // Create a loading archive. myFile.SeekToBegin(); CArchive arLoad(&myFile, CArchive::load); // Verify the object is in the archive. pAge = (CAge*) arLoad.ReadObject(RUNTIME_CLASS(CAge)); ASSERT(age == *pAge);

CArchive是MFC封装的一个非常有用的文件处理类,我们可以在我们需要串行化数据处理的时候使用他。

对于CArchive类的其他使用和详细信息,可参考MSDN上的说明。

你可能感兴趣的:(框架,object,存储,Class,文档,character)