CArchive

允许将复杂的对象网络以永久二进制格式(通常为磁盘存储)保存,此格式在这些对象被删除后仍然存在。

语法

class CArchive

成员

公共构造函数

名称 描述
CArchive::CArchive 创建一个 CArchive 对象。

公共方法

名称 描述
CArchive::Abort 关闭存档而不引发异常。
CArchive::Close 刷新未写入的数据并断开与 CFile 的连接。
CArchive::Flush 刷新存档缓冲区中未写入的数据。
CArchive::GetFile 获取此存档的 CFile 对象指针。
CArchive::GetObjectSchema Serialize 函数调用,以确定要反序列化的对象的版本。
CArchive::IsBufferEmpty 确定缓冲区是否在 Windows 套接字接收过程中被清空。
CArchive::IsLoading 确定存档是否正在加载数据。
CArchive::IsStoring 确定存档是否正在存储数据。
CArchive::MapObject 将未序列化到文件但可供子对象引用的对象放在映射中。
CArchive::Read 读取原始字节。
CArchive::ReadClass 读取以前使用 WriteClass 存储的类引用。
CArchive::ReadObject 调用对象的 Serialize 函数进行加载。
CArchive::ReadString 读取单行文本。
CArchive::SerializeClass 根据 CArchive 的方向读取或写入对 CArchive 对象的类引用。
CArchive::SetLoadParams 设置负载数组增长的大小。 必须在加载任何对象之前或者在调用 MapObjectReadObject 之前调用。
CArchive::SetObjectSchema 设置存储在存档对象中的对象架构。
CArchive::SetStoreParams 设置用于在序列化过程中标识唯一对象的映射的哈希表大小和块大小。
CArchive::Write 写入原始字节。
CArchive::WriteClass 将对 CRuntimeClass 的引用写入 CArchive
CArchive::WriteObject 调用对象的 Serialize 函数进行存储。
CArchive::WriteString 写入单行文本。

公共运算符

“属性” 描述
CArchive::operator << 将对象和基元类型存储在存档中。
CArchive::operator >> 从存档加载对象和基元类型。

公共数据成员

“属性” 描述
CArchive::m_pDocument

注解

CArchive 没有基类。

稍后可以从持久存储中加载对象,并在内存中重构。 这种使数据持久化的过程称为“序列化”。

可以将存档对象视为一种二进制流。 与输入/输出流一样,存档与文件关联,并允许在存储中缓冲写入和读取数据。 输入/输出流处理 ASCII 字符序列,但存档以高效、非冗余格式处理二进制对象数据。

必须先创建 CFile 对象,然后才能创建 CArchive 对象。 此外,必须确保存档的加载/存储状态与文件的打开模式兼容。 每个文件只能有一个活动存档。

构造 CArchive 对象时,将其附加到表示打开的文件的类 CFile(或派生类)的对象。 还可以指定存档是用于加载还是存储。 CArchive 对象不仅可以处理基元类型,还可以处理为序列化设计的 CObject 派生类的对象。 可序列化类通常具有 Serialize 成员函数,并且通常使用 DECLARE_SERIALIMPLEMENT_SERIAL 宏,如类 CObject 中所述。

重载的提取 (>>) 和插入 (<<) 运算符是支持基元类型和 CObject 派生类的便捷存档编程接口。

CArchive 还支持使用 MFC Windows 套接字类 CSocketCSocketFile 进行编程。 IsBufferEmpty 成员函数支持这种用法。

有关 CArchive 的详细信息,请参阅文章序列化Windows 套接字:对存档使用套接字

继承层次结构

CArchive

要求

标头afx.h

CArchive::Abort

调用此函数以关闭存档而不引发异常。

void Abort ();

备注

CArchive 析构函数通常会调用 Close,这将刷新任何尚未保存到关联 CFile 对象的数据。 这可能会导致异常。

捕获这些异常时,最好使用 Abort,以便析构 CArchive 对象不会导致进一步的异常。 处理异常时,CArchive::Abort 不会在失败时引发异常,因为与 CArchive::Close 不同,Abort 会忽略失败。

如果使用 new 在堆上分配了 CArchive 对象,则必须在关闭文件之后删除该对象。

示例

请参阅 CArchive::WriteClass 的示例。

CArchive::CArchive

构造 CArchive 对象,并指定它是用于加载还是存储对象。

CArchive(
    CFile* pFile,
    UINT nMode,
    int nBufSize = 4096,
    void* lpBuf = NULL);

参数

pFile
指向 CFile 对象的指针,该对象是持久数据的最终源或目标。

nMode
一个标志,指定对象是从存档加载还是存储到存档。 nMode 参数必须具有以下值之一:

  • CArchive::load 从存档加载数据。 只需要 CFile 读取权限。

  • CArchive::store 将数据保存到存档。 需要 CFile 写入权限。

  • CArchive::bNoFlushOnDelete 防止存档在调用存档析构函数时自动调用 Flush。 如果设置此标志,则需要在调用析构函数之前显式调用 Close。 否则,数据将损坏。

nBufSize
一个整数,指定内部文件缓冲区的大小(以字节为单位)。 请注意,默认缓冲区大小为 4,096 字节。 如果经常存档大型对象,使用更大的缓冲区大小(文件缓冲区大小的倍数)可以提高性能。

lpBuf
一个可选指针,指向用户提供的大小为 nBufSize 的缓冲区。 如果不指定此参数,存档会从本地堆中分配一个缓冲区,并在对象被销毁时释放该缓冲区。 存档不会释放用户提供的缓冲区。

备注

创建存档后,无法更改此规范。

在关闭存档之前,不得使用 CFile 操作来更改文件的状态。 任何此类操作都会破坏存档的完整性。 可以在序列化过程中随时访问文件指针的位置,方法是从 GetFile 成员函数获取存档的文件对象,然后使用 CFile::GetPosition 函数。 应在获取文件指针的位置之前调用 CArchive::Flush

示例

CFile file;
TCHAR szBuf[512];
if (!file.Open(_T("CArchive__test__file.txt"),
               CFile::modeCreate | CFile::modeWrite))
{
#ifdef _DEBUG
   AFXDUMP(_T("Unable to open file\n"));
   exit(1);
#endif
}
CArchive ar(&file, CArchive::store, 512, szBuf);

CArchive::Close

刷新缓冲区中剩余的所有数据,关闭存档,并将存档与文件断开连接。

void Close();

备注

不允许对存档进行进一步操作。 关闭存档后,可以为同一文件创建另一个存档,也可以关闭该文件。

成员函数 Close 确保所有数据都从存档传输到文件,并使存档不可用。 若要完成从文件到存储介质的传输,必须先使用 CFile::Close,然后销毁 CFile 对象。

示例

请参阅 CArchive::WriteString 的示例。

CArchive::Flush

强制将存档缓冲区中剩余的所有数据写入文件。

void Flush();

备注

成员函数 Flush 确保将所有数据从存档传输到文件。 必须调用 CFile::Close 以完成从文件到存储介质的传输。

示例

CFile myFile(_T("CArchive__test__file.txt"),
             CFile::modeCreate | CFile::modeWrite);
CArchive ar(&myFile, CArchive::store);

// Write a string to the archive.
ar.WriteString(_T("My string."));

// Flush all of the data to the file.
ar.Flush();

CArchive::GetFile

获取此存档的 CFile 对象指针。

CFile* GetFile() const;

返回值

指向正在使用的 CFile 对象的常量指针。

备注

在使用 GetFile 之前,必须刷新存档。

示例

const CFile *fp = ar.GetFile();

CArchive::GetObjectSchema

Serialize 函数调用此函数以确定当前正在反序列化的对象的版本。

UINT GetObjectSchema();

返回值

在反序列化期间,正在读取的对象的版本。

备注

仅当加载 CArchive 对象(CArchive::IsLoading 返回非零)时,调用此函数才有效。 它应该是 Serialize 函数中的第一个调用,并且只调用一次。 返回值 (UINT)-1 指示版本号未知。

CObject 派生类可以将 VERSIONABLE_SCHEMA 与架构版本本身(在 IMPLEMENT_SERIAL 宏中)结合使用(使用按位“or”(|))来创建“可版本化对象”,即 Serialize 成员函数可以读取多个版本的对象。 默认框架功能(不带 VERSIONABLE_SCHEMA)是在版本不匹配时引发异常。

示例

IMPLEMENT_SERIAL(CSchemaObject, CObject, VERSIONABLE_SCHEMA | 1)

void CSchemaObject::Serialize(CArchive &ar)
{
   CObject::Serialize(ar);

   if (ar.IsLoading())
   {
      int nVersion = ar.GetObjectSchema();

      switch (nVersion)
      {
      case 0:
         // read in previous version of
         // this object
         break;
      case 1:
         // read in current version of
         // this object
         break;
      default:
         // report unknown version of
         // this object
         break;
      }
   }
   else
   {
      // Normal storing code goes here
   }
}

CArchive::IsBufferEmpty

调用此成员函数以确定存档对象的内部缓冲区是否为空。

BOOL IsBufferEmpty() const;

返回值

如果存档的缓冲区为空,则为非零;否则为 0。

注解

提供此函数是为了支持使用 MFC Windows 套接字类 CSocketFile 进行编程。 无需将其用于与 CFile 对象关联的存档。

之所以将 IsBufferEmptyCSocketFile 对象关联的存档结合使用,是因为存档的缓冲区可能包含多个消息或记录。 收到一条消息后,应使用 IsBufferEmpty 来控制继续接收数据直到缓冲区为空的循环。 有关详细信息,请参阅类 CAsyncSocketReceive 成员函数,它显示了如何使用 IsBufferEmpty

有关详细信息,请参阅 Windows 套接字:对存档使用套接字

CArchive::IsLoading

确定存档是否正在加载数据。

BOOL IsLoading() const;

返回值

如果存档当前用于加载,则为非零;否则为 0。

备注

此成员函数由存档类的 Serialize 函数调用。

示例

int i = 0;
if (ar.IsLoading())
   ar >> i;
else
   ar << i;

CArchive::IsStoring

确定存档是否正在存储数据。

BOOL IsStoring() const;

返回值

如果存档当前用于存储,则为非零;否则为 0。

注解

此成员函数由存档类的 Serialize 函数调用。

如果存档的 IsStoring 状态为非零,则其 IsLoading 状态为 0,反之亦然。

示例

int i = 0;
if (ar.IsStoring())
   ar << i;
else
   ar >> i;

CArchive::MapObject

调用此成员函数,以将并未真正序列化到文件但可供子对象引用的对象放在映射中。

void MapObject(const CObject* pOb);

参数

pOb
指向要存储的对象的常量指针。

注解

例如,你可能不会序列化文档,但会序列化文档中的项。 通过调用 MapObject,可以允许这些项或子对象引用文档。 此外,已序列化的子项可以序列化其 m_pDocument 后向指针。

存储到 CArchive 对象以及从中加载时,可以调用 MapObjectMapObject 会在序列化和反序列化过程中将指定对象添加到 CArchive 对象维护的内部数据结构中,但与 ReadObjectWriteObject 不同的是,它不对对象调用序列化。

示例

//MyDocument.h
class CMyDocument : public CDocument
{
public:
   DECLARE_SERIAL(CMyDocument)

   CObList m_listOfSubItems;

   virtual void Serialize(CArchive &ar);
};

 

//MyDocument.cpp
IMPLEMENT_SERIAL(CMyDocument, CDocument, 1)

void CMyDocument::Serialize(CArchive& ar)
{
   CDocument::Serialize(ar);

   if (ar.IsStoring())
   {
      // TODO: add storing code here
   }
   else
   {
      // TODO: add loading code here
   }

   ar.MapObject(this);

   //serialize the subitems in the document;
   //they will be able to serialize their m_pDoc
   //back pointer
   m_listOfSubItems.Serialize(ar);
}

 

//SubItem.h
class CSubItem : public CObject
{
   DECLARE_SERIAL(CSubItem)
   CSubItem() : m_i(0){};

public:
   CSubItem(CMyDocument *pDoc)
   {
      m_pDoc = pDoc;
   }

   // back pointer to owning document
   CMyDocument *m_pDoc;
   WORD m_i; // other item data

   virtual void Serialize(CArchive &ar);
};

 

//SubItem.cpp
IMPLEMENT_SERIAL(CSubItem, CObject, 1);

void CSubItem::Serialize(CArchive &ar)

{
   if (ar.IsStoring())
   {
      // will serialize a reference
      // to the "mapped" document pointer
      ar << (CObject *)m_pDoc;
      ar << m_i;
   }
   else
   {
      // Will load a reference to
      // the "mapped" document pointer
      ar >> (CObject *&)m_pDoc;
      ar >> m_i;
   }
}

CArchive::m_pDocument

默认设置为 NULL,此指向 CDocument 的指针可以设置为 CArchive 实例的用户想要的任何内容。

CDocument* m_pDocument;

注解

此指针的常见用法是向所有正在序列化的对象传达有关序列化过程的附加信息。 为此,需要使用正在序列化的文档(CDocument 派生类)初始化指针,这样一来,文档中的对象就可以在必要时访问文档。 COleClientItem 对象在序列化期间也使用此指针。

当用户发出“打开文件”或“保存文件”命令时,框架会将 m_pDocument 设置为正在序列化的文档。 如果不是因“打开文件”或“保存文件”命令序列化对象链接与嵌入 (OLE) 容器文档,则必须显式设置 m_pDocument。 例如,将容器文档序列化到剪贴板时,需要执行此操作。

示例

CFile myFile(_T("My__test__file.dat"),
             CFile::modeCreate | CFile::modeWrite);
CArchive ar(&myFile, CArchive::store);
CMyDocument mydoc;
ar.m_pDocument = &mydoc;

// Serialize the document to the archive.
if (ar.m_pDocument != NULL)
   ar.m_pDocument->Serialize(ar);

CArchive::operator <<

将指示的对象或基元类型存储到存档中。

friend CArchive& operator<<(
    CArchive& ar,
    const CObject* pOb);

throw(
    CArchiveException*,
    CFileException*);

CArchive& AFXAPI operator<<(
    CArchive& ar,
    const RECT& rect);

CArchive& AFXAPI operator<<(
    CArchive& ar,
    POINT point);

CArchive& AFXAPI operator<<(
    CArchive& ar,
    SIZE size);

template<typename BaseType,
    class StringTraits> CArchive& operator<<(
    const ATL::CStringT<BaseType,
    StringTraits>& str);

CArchive& operator<<(BYTE by);
CArchive& operator<<(WORD w);
CArchive& operator<<(LONG l);
CArchive& operator<<(DWORD dw);
CArchive& operator<<(float f);
CArchive& operator<<(double d);
CArchive& operator<<(int i);
CArchive& operator<<(short w);
CArchive& operator<<(char ch);
CArchive& operator<<(wchar_t ch);
CArchive& operator<<(unsigned u);
CArchive& operator<<(bool b);
CArchive& operator<<(ULONGLONG dwdw);
CArchive& operator<<(LONGLONG dwdw);

返回值

一个 CArchive 引用,用于在单行上启用多个插入运算符。

备注

上述最后两个版本专门用于存储 64 位整数。

如果在类实现中使用了 IMPLEMENT_SERIAL 宏,则为 CObject 重载的插入运算符会调用受保护的 WriteObject。 此函数又会调用类的 Serialize 函数。

CStringT 插入运算符 (<<) 支持诊断转储和存储到存档。

示例

此示例演示了如何将 CArchive 插入运算符 <<intlong 类型结合使用。

long l = 5;
int i = 10;
if (ar.IsStoring())
   ar << l << i;

此示例演示了如何将 CArchive 插入运算符 <<CStringT 类型结合使用。

CString s("abc");
ar << s; // Prints the value (abc)

CArchive::operator >>

从存档中加载指定的对象或基元类型。

friend CArchive& operator>>(
    CArchive& ar,
    CObject *& pOb);

throw(
    CArchiveException*,
    CFileException*,
    CMemoryException*);

friend CArchive& operator>>(
    CArchive& ar,
    const CObject *& pOb);

throw(
    CArchiveException*,
    CFileException*,
    CMemoryException*);

CArchive& AFXAPI operator>>(
    CArchive& ar,
    const RECT& rect);

CArchive& AFXAPI operator>>(
    CArchive& ar,
    POINT point);

CArchive& AFXAPI operator>>(
    CArchive& ar,
    SIZE size);

template<typename BaseType,
    class StringTraits> CArchive& operator>>(
    ATL::CStringT<BaseType,
    StringTraits>& str);

CArchive& operator>>(BYTE& by);
CArchive& operator>>(WORD& w);
CArchive& operator>>(int& i);
CArchive& operator>>(LONG& l);
CArchive& operator>>(DWORD& dw);
CArchive& operator>>(float& f);
CArchive& operator>>(double& d);
CArchive& operator>>(short& w);
CArchive& operator>>(char& ch);
CArchive& operator>>(wchar_t& ch);
CArchive& operator>>(unsigned& u);
CArchive& operator>>(bool& b);
CArchive& operator>>(ULONGLONG& dwdw);
CArchive& operator>>(LONGLONG& dwdw);

返回值

一个 CArchive 引用,用于在单行上启用多个提取运算符。

备注

上述最后两个版本专门用于加载 64 位整数。

如果在类实现中使用了 IMPLEMENT_SERIAL 宏,则为 CObject 重载的提取运算符会调用受保护的 ReadObject 函数(使用非零运行时类指针)。 此函数又会调用类的 Serialize 函数。

CStringT 提取运算符 (>>) 支持从存档加载。

示例

此示例演示了如何将 CArchive 提取运算符 >>int 类型结合使用。

long l;
int i;
if (ar.IsLoading())
   ar >> l >> i;

此示例演示了如何将 CArchive 插入和提取运算符 <<>>CStringT 类型结合使用。

CString s;
if (ar.IsLoading())
   ar >> s;

CArchive::Read

从存档中读取指定的字节数。

UINT Read(void* lpBuf, UINT nMax);

参数

lpBuf
指向用户提供的缓冲区的指针,该缓冲区将接收从存档读取的数据。

nMax
一个无符号整数,指定要从存档读取的字节数。

返回值

一个无符号整数,包含实际读取的字节数。 如果返回值小于请求的数字,则已到达文件尾。 文件尾状态不会引发异常。

备注

存档不会解释字节。

可以在 Serialize 函数中使用 Read 成员函数来读取对象中包含的普通结构。

示例

char pbRead[100];
ar.Read(pbRead, 100);

CArchive::ReadClass

调用此成员函数以读取对先前使用 WriteClass 存储的类的引用。

CRuntimeClass* ReadClass(
    const CRuntimeClass* pClassRefRequested = NULL,
    UINT* pSchema = NULL,
    DWORD* pObTag = NULL);

参数

pClassRefRequested
指向 CRuntimeClass 结构的指针,该结构对应于请求的类引用。 可以为 NULL

pSchema
一个指针,指向先前存储的运行时类的架构。

pObTag
一个数字,引用对象的唯一标记。 由 ReadObject 的实现在内部使用。 仅公开用于高级编程;pObTag 通常应为 NULL

返回值

指向 CRuntimeClass 结构的指针。

备注

如果 pClassRefRequested 不为 NULLReadClass 将验证存档的类信息是否与运行时类兼容。 如果不兼容,ReadClass 将引发 CArchiveException

运行时类必须使用 DECLARE_SERIALIMPLEMENT_SERIAL;否则,ReadClass 将引发 CNotSupportedException

如果 pSchemaNULL,则可以通过调用 CArchive::GetObjectSchema 来检索存储类的架构;否则,*pSchema 将包含先前存储的运行时类的架构。

可以使用 SerializeClass 而不是 ReadClass,以同时处理类引用的读取和写入。

示例

请参阅 CArchive::WriteClass 的示例。

CArchive::ReadObject

从存档中读取对象数据,并构造相应类型的对象。

CObject* ReadObject(const CRuntimeClass* pClass);

参数

pClass
指向 CRuntimeClass 结构的常量指针,该结构对应于你希望读取的对象。

返回值

一个 CObject 指针,该指针必须使用 CObject::IsKindOf 安全地强制转换为正确的派生类。

备注

此函数通常由为 CObject 指针重载的 CArchive 提取 (>>) 运算符调用。 ReadObject 又会调用存档类的 Serialize 函数。

如果提供 RUNTIME_CLASS 宏获取的非零 pClass 参数,该函数将验证存档对象的运行时类。 这假设你在类实现中使用了 IMPLEMENT_SERIAL 宏。

示例

请参阅 CArchive::WriteObject 的示例。

CArchive::ReadString

调用此成员函数,以将文本数据从与 CArchive 对象关联的文件读入缓冲区。

BOOL ReadString(CString& rString);
LPTSTR ReadString(LPTSTR lpsz, UINT nMax);

参数

rString
CString 的引用,该类将包含从与 CArchive 对象关联的文件中读取数据后的结果字符串。

lpsz
指定一个指向用户提供的缓冲区的指针,该缓冲区将接收以 null 结尾的文本字符串。

nMax
指定要读取的最大字符数。 应比 lpsz 缓冲区的大小小一。

返回值

在返回 BOOL 的版本中,如果成功,则为 TRUE;否则为 FALSE

在返回 LPTSTR 的版本中,为指向包含文本数据的缓冲区的指针;如果到达文件尾,则为 NULL

注解

在带有 nMax 参数的成员函数版本中,缓冲区最多可容纳 nMax - 1 个字符。 读取由回车换行符对停止。 始终移除尾随换行符。 在任何一种情况下都会追加一个 NULL 字符 ('\0')。

CArchive::Read 也可用于文本模式输入,但它不会以回车换行符对终止。

示例

请参阅 CArchive::WriteString 的示例。

CArchive::SerializeClass

如果要存储和加载基类的版本信息,请调用此成员函数。

void SerializeClass(const CRuntimeClass* pClassRef);

参数

pClassRef
指向基类的运行时类对象的指针。

备注

SerializeClass 根据 CArchive 的方向读取或写入对 CArchive 对象的类的引用。 可使用 SerializeClass 代替 ReadClassWriteClass 作为序列化基类对象的便捷方式;SerializeClass 需要的代码和参数更少。

ReadClass 一样,SerializeClass 将验证存档的类信息是否与运行时类兼容。 如果不兼容,SerializeClass 将引发 CArchiveException

运行时类必须使用 DECLARE_SERIALIMPLEMENT_SERIAL;否则,SerializeClass 将引发 CNotSupportedException

使用 RUNTIME_CLASS 宏检索 pRuntimeClass 参数的值。 基类必须使用 IMPLEMENT_SERIAL 宏。

示例

class CBaseClass : public CObject
{
   DECLARE_SERIAL(CBaseClass);
};
class CDerivedClass : public CBaseClass
{
public:
   virtual void Serialize(CArchive &ar);
};
void CDerivedClass::Serialize(CArchive &ar)
{
   if (ar.IsStoring())
   {
      //normal code for storing contents
      //of this object
   }
   else
   {
      //normal code for reading contents
      //of this object
   }

   //allow the base class to serialize along
   //with its version information
   ar.SerializeClass(RUNTIME_CLASS(CBaseClass));
   CBaseClass::Serialize(ar);
}

CArchive::SetLoadParams

要从存档中读取大量 SetLoadParams 派生对象时调用 CObject

void SetLoadParams(UINT nGrowBy = 1024);

参数

nGrowBy
需要增加大小时要分配的最小元素槽数。

备注

CArchive 使用加载数组来解析对存档中存储的对象的引用。 SetLoadParams 允许设置加载数组增长的大小。

不得在加载任何对象之后或者在调用 MapObjectReadObject 之后调用 SetLoadParams

示例

class CMyLargeDocument : public CDocument
{
public:
   virtual void Serialize(CArchive &ar);
};
void CMyLargeDocument::Serialize(CArchive &ar)
{
   if (ar.IsStoring())
      ar.SetStoreParams(); // use large defaults
   else
      ar.SetLoadParams();

   if (ar.IsStoring())
   {
      // code for storing CMyLargeDocument
   }
   else
   {
      // code for loading CMyLargeDocument
   }
}

CArchive::SetObjectSchema

调用此成员函数以将存储在存档对象中的对象架构设置为 nSchema

void SetObjectSchema(UINT nSchema);

参数

nSchema
指定对象的架构。

备注

GetObjectSchema 的下一次调用将返回存储在 nSchema 中的值。

使用 SetObjectSchema 进行高级版本控制;例如,当你想要强制在派生类的 Serialize 函数中读取特定版本时。

示例

ar.SetObjectSchema(2);
ASSERT(2 == ar.GetObjectSchema());

CArchive::SetStoreParams

在存档中存储大量 CObject 派生对象时使用 SetStoreParams

void SetStoreParams(UINT nHashSize = 2053, UINT nBlockSize = 128);

参数

nHashSize
接口指针映射的哈希表的大小。 应为素数。

nBlockSize
指定用于扩展参数的内存分配粒度。 应为 2 的幂,以获得最佳性能。

备注

SetStoreParams 允许设置用于在序列化过程中标识唯一对象的映射的哈希表大小和块大小。

不得在存储任何对象之后或者在调用 MapObjectWriteObject 之后调用 SetStoreParams

示例

class CMyLargeDocument : public CDocument
{
public:
   virtual void Serialize(CArchive &ar);
};
void CMyLargeDocument::Serialize(CArchive &ar)
{
   if (ar.IsStoring())
      ar.SetStoreParams(); // use large defaults
   else
      ar.SetLoadParams();

   if (ar.IsStoring())
   {
      // code for storing CMyLargeDocument
   }
   else
   {
      // code for loading CMyLargeDocument
   }
}

CArchive::Write

将指定的字节数写入存档。

void Write(const void* lpBuf, INT nMax);

参数

lpBuf
指向用户提供的缓冲区的指针,该缓冲区包含要写入存档的数据。

nMax
一个整数,指定要写入存档的字节数。

备注

存档不格式化字节。

可以在 Serialize 函数中使用 Write 成员函数写入对象中包含的普通结构。

示例

char pbWrite[100];
memset(pbWrite, 'a', 100);
ar.Write(pbWrite, 100);

CArchive::WriteClass

在派生类的序列化过程中,使用 WriteClass 存储基类的版本和类信息。

void WriteClass(const CRuntimeClass* pClassRef);

参数

pClassRef
指向 CRuntimeClass 结构的指针,该结构对应于请求的类引用。

注解

WriteClass 将对基类的 CRuntimeClass 的引用写入 CArchive。 使用 CArchive::ReadClass 检索该引用。

WriteClass 验证存档的类信息是否与运行时类兼容。 如果不兼容,WriteClass 将引发 CArchiveException

运行时类必须使用 DECLARE_SERIALIMPLEMENT_SERIAL;否则,WriteClass 将引发 CNotSupportedException

可以使用 SerializeClass 而不是 WriteClass,以同时处理类引用的读取和写入。

示例

CFile myFile(_T("My__test__file.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();
}

CArchive::WriteObject

将指定的 CObject 存储到存档中。

void WriteObject(const CObject* pOb);

参数

pOb
指向要存储的对象的常量指针。

备注

此函数通常由为 CObject 重载的 CArchive 插入 (<<) 运算符调用。 WriteObject 又会调用存档类的 Serialize 函数。

必须使用 IMPLEMENT_SERIAL 宏来启用存档。 WriteObject 将 ASCII 类名写入存档。 稍后在加载过程中验证此类名。 特殊编码方案可防止类的多个对象不必要地重复类名。 该方案还可以防止冗余存储作为多个指针的目标的对象。

确切的对象编码方法(包括 ASCII 类名的存在)是一个实现细节,可能会在库的未来版本中发生变化。

注意

在开始存档对象之前完成所有对象的创建、删除和更新。 如果将存档与对象修改混合在一起,存档会损坏。

示例

有关类 CAge 的定义,请参阅 CObList::CObList 的示例。

CFile myFile(_T("My__test__file.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::WriteString

使用此成员函数将数据从缓冲区写入与 CArchive 对象关联的文件。

void WriteString(LPCTSTR lpsz);

参数

lpsz
指定指向缓冲区的指针,该缓冲区包含以 null 结尾的文本字符串。

备注

终止空字符 ('\0') 不会写入文件;换行符也不会自动写入。

WriteString 会引发异常来响应多种状态,包括磁盘已满状态。

Write 也可用,但不是以空字符结尾,而是将请求的字节数写入文件。

示例

CFile myFile(_T("My__test__file.dat"),
             CFile::modeCreate | CFile::modeReadWrite);
CString str1("String1"), str2("String2"), str;

// Create a storing archive.
CArchive arStore(&myFile, CArchive::store);

// Write str1 and str2 to the archive
arStore.WriteString(str1);
arStore.WriteString(_T("\n"));
arStore.WriteString(str2);
arStore.WriteString(_T("\n"));

// Close the storing archive
arStore.Close();

// Create a loading archive.
myFile.SeekToBegin();
CArchive arLoad(&myFile, CArchive::load);

// Verify the two strings are in the archive.
arLoad.ReadString(str);
ASSERT(str == str1);
arLoad.ReadString(str);
ASSERT(str == str2);

另请参阅

层次结构图
CFile
CObject
CSocket
CSocketFile