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 |
设置负载数组增长的大小。 必须在加载任何对象之前或者在调用 MapObject 或 ReadObject 之前调用。 |
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_SERIAL
和 IMPLEMENT_SERIAL
宏,如类 CObject
中所述。
重载的提取 (>>
) 和插入 (<<
) 运算符是支持基元类型和 CObject
派生类的便捷存档编程接口。
CArchive
还支持使用 MFC Windows 套接字类 CSocket
和 CSocketFile
进行编程。 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
对象关联的存档。
之所以将 IsBufferEmpty
与 CSocketFile
对象关联的存档结合使用,是因为存档的缓冲区可能包含多个消息或记录。 收到一条消息后,应使用 IsBufferEmpty
来控制继续接收数据直到缓冲区为空的循环。 有关详细信息,请参阅类 CAsyncSocket
的 Receive
成员函数,它显示了如何使用 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
对象以及从中加载时,可以调用 MapObject
。 MapObject
会在序列化和反序列化过程中将指定对象添加到 CArchive
对象维护的内部数据结构中,但与 ReadObject
和 WriteObject
不同的是,它不对对象调用序列化。
示例
//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
插入运算符 <<
与 int
和 long
类型结合使用。
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
不为 NULL
,ReadClass
将验证存档的类信息是否与运行时类兼容。 如果不兼容,ReadClass
将引发 CArchiveException
。
运行时类必须使用 DECLARE_SERIAL
和 IMPLEMENT_SERIAL
;否则,ReadClass
将引发 CNotSupportedException
。
如果 pSchema
为 NULL
,则可以通过调用 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
代替 ReadClass
和 WriteClass
作为序列化基类对象的便捷方式;SerializeClass
需要的代码和参数更少。
与 ReadClass
一样,SerializeClass
将验证存档的类信息是否与运行时类兼容。 如果不兼容,SerializeClass
将引发 CArchiveException
。
运行时类必须使用 DECLARE_SERIAL
和 IMPLEMENT_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
允许设置加载数组增长的大小。
不得在加载任何对象之后或者在调用 MapObject
或 ReadObject
之后调用 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
允许设置用于在序列化过程中标识唯一对象的映射的哈希表大小和块大小。
不得在存储任何对象之后或者在调用 MapObject
或 WriteObject
之后调用 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_SERIAL
和 IMPLEMENT_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);