CArchive Class

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

Syntax

class CArchive

Members

Public Constructors

Name Description
CArchive::CArchive Creates a CArchive object.

Public Methods

Name Description
CArchive::Abort Closes an archive without throwing an exception.
CArchive::Close Flushes unwritten data and disconnects from the CFile.
CArchive::Flush Flushes unwritten data from the archive buffer.
CArchive::GetFile Gets the CFile object pointer for this archive.
CArchive::GetObjectSchema Called from the Serialize function to determine the version of the object that is being deserialized.
CArchive::IsBufferEmpty Determines whether the buffer has been emptied during a Windows Sockets receive process.
CArchive::IsLoading Determines whether the archive is loading.
CArchive::IsStoring Determines whether the archive is storing.
CArchive::MapObject Places objects in the map that are not serialized to the file, but that are available for subobjects to reference.
CArchive::Read Reads raw bytes.
CArchive::ReadClass Reads a class reference previously stored with WriteClass.
CArchive::ReadObject Calls an object's Serialize function for loading.
CArchive::ReadString Reads a single line of text.
CArchive::SerializeClass Reads or writes the class reference to the CArchive object depending on the direction of the CArchive.
CArchive::SetLoadParams Sets the size to which the load array grows. Must be called before any object is loaded or before MapObject or ReadObject is called.
CArchive::SetObjectSchema Sets the object schema stored in the archive object.
CArchive::SetStoreParams Sets the hash table size and the block size of the map used to identify unique objects during the serialization process.
CArchive::Write Writes raw bytes.
CArchive::WriteClass Writes a reference to the CRuntimeClass to the CArchive.
CArchive::WriteObject Calls an object's Serialize function for storing.
CArchive::WriteString Writes a single line of text.

Public Operators

Name Description
CArchive::operator << Stores objects and primitive types to the archive.
CArchive::operator >> Loads objects and primitive types from the archive.

Public Data Members

Name Description
CArchive::m_pDocument

Remarks

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."

You can think of an archive object as a kind of binary stream. Like an input/output stream, an archive is associated with a file and permits the buffered writing and reading of data to and from storage. An input/output stream processes sequences of ASCII characters, but an archive processes binary object data in an efficient, nonredundant format.

You must create a CFile object before you can create a CArchive object. In addition, you must ensure that the archive's load/store status is compatible with the file's open mode. You are limited to one active archive per file.

When you construct a CArchive object, you attach it to an object of class CFile (or a derived class) that represents an open file. You also specify whether the archive will be used for loading or storing. A CArchive object can process not only primitive types but also objects of CObject-derived classes designed for serialization. A serializable class usually has a Serialize member function, and it usually uses the DECLARE_SERIAL and IMPLEMENT_SERIAL macros, as described under class CObject.

The overloaded extraction ( >>) and insertion ( <<) operators are convenient archive programming interfaces that support both primitive types and CObject-derived classes.

CArchive also supports programming with the MFC Windows Sockets classes CSocket and CSocketFile. The IsBufferEmpty member function supports that usage.

For more information on CArchive, see the articles Serialization and Windows Sockets: Using Sockets with Archives.

Inheritance Hierarchy

CArchive

Requirements

Header: afx.h

CArchive::Abort

Call this function to close the archive without throwing an exception.

void Abort ();

Remarks

The CArchive destructor will normally call Close, which will flush any data that has not been saved to the associated CFile object. This can cause exceptions.

When catching these exceptions, it is a good idea to use Abort, so that destructing the CArchive object doesn't cause further exceptions. When handling exceptions, CArchive::Abort will not throw an exception on failures because, unlike CArchive::Close, Abort ignores failures.

If you used new to allocate the CArchive object on the heap, then you must delete it after closing the file.

Example

See the example for CArchive::WriteClass.

CArchive::CArchive

Constructs a CArchive object and specifies whether it will be used for loading or storing objects.

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

Parameters

pFile
A pointer to the CFile object that is the ultimate source or destination of the persistent data.

nMode
A flag that specifies whether objects will be loaded from or stored to the archive. The nMode parameter must have one of the following values:

  • CArchive::load Loads data from the archive. Requires only CFile read permission.

  • CArchive::store Saves data to the archive. Requires CFile write permission.

  • CArchive::bNoFlushOnDelete Prevents the archive from automatically calling Flush when the archive destructor is called. If you set this flag, you are responsible for explicitly calling Close before the destructor is called. If you do not, your data will be corrupted.

nBufSize
An integer that specifies the size of the internal file buffer, in bytes. Note that the default buffer size is 4,096 bytes. If you routinely archive large objects, you will improve performance if you use a larger buffer size that is a multiple of the file buffer size.

lpBuf
An optional pointer to a user-supplied buffer of size nBufSize. If you do not specify this parameter, the archive allocates a buffer from the local heap and frees it when the object is destroyed. The archive does not free a user-supplied buffer.

Remarks

You cannot change this specification after you have created the archive.

You may not use CFile operations to alter the state of the file until you have closed the archive. Any such operation will damage the integrity of the archive. You may access the position of the file pointer at any time during serialization by obtaining the archive's file object from the GetFile member function and then using the CFile::GetPosition function. You should call CArchive::Flush before obtaining the position of the file pointer.

Example

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

Flushes any data remaining in the buffer, closes the archive, and disconnects the archive from the file.

void Close();

Remarks

No further operations on the archive are permitted. After you close an archive, you can create another archive for the same file or you can close the file.

The member function Close ensures that all data is transferred from the archive to the file, and it makes the archive unavailable. To complete the transfer from the file to the storage medium, you must first use CFile::Close and then destroy the CFile object.

Example

See the example for CArchive::WriteString.

CArchive::Flush

Forces any data remaining in the archive buffer to be written to the file.

void Flush();

Remarks

The member function Flush ensures that all data is transferred from the archive to the file. You must call CFile::Close to complete the transfer from the file to the storage medium.

Example

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

Gets the CFile object pointer for this archive.

CFile* GetFile() const;

Return Value

A constant pointer to the CFile object in use.

Remarks

You must flush the archive before using GetFile.

Example

const CFile *fp = ar.GetFile();

CArchive::GetObjectSchema

Call this function from the Serialize function to determine the version of the object that is currently being deserialized.

UINT GetObjectSchema();

Return Value

During deserialization, the version of the object being read.

Remarks

Calling this function is only valid when the CArchive object is being loaded ( CArchive::IsLoading returns nonzero). It should be the first call in the Serialize function and called only once. A return value of ( UINT)-1 indicates that the version number is unknown.

A CObject-derived class may use VERSIONABLE_SCHEMA combined (using bitwise "or" (|)) with the schema version itself (in the IMPLEMENT_SERIAL macro) to create a "versionable object," that is, an object whose Serialize member function can read multiple versions. The default framework functionality (without VERSIONABLE_SCHEMA) is to throw an exception when the version is mismatched.

Example

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

Call this member function to determine whether the archive object's internal buffer is empty.

BOOL IsBufferEmpty() const;

Return Value

Nonzero if the archive's buffer is empty; otherwise 0.

Remarks

This function is supplied to support programming with the MFC Windows Sockets class CSocketFile. You do not need to use it for an archive associated with a CFile object.

The reason for using IsBufferEmpty with an archive associated with a CSocketFile object is that the archive's buffer might contain more than one message or record. After receiving one message, you should use IsBufferEmpty to control a loop that continues receiving data until the buffer is empty. For more information, see the Receive member function of class CAsyncSocket, which shows how to use IsBufferEmpty.

For more information, see Windows Sockets: Using Sockets with Archives.

CArchive::IsLoading

Determines whether the archive is loading data.

BOOL IsLoading() const;

Return Value

Nonzero if the archive is currently being used for loading; otherwise 0.

Remarks

This member function is called by the Serialize functions of the archived classes.

Example

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

CArchive::IsStoring

Determines whether the archive is storing data.

BOOL IsStoring() const;

Return Value

Nonzero if the archive is currently being used for storing; otherwise 0.

Remarks

This member function is called by the Serialize functions of the archived classes.

If the IsStoring status of an archive is nonzero, then its IsLoading status is 0, and vice versa.

Example

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

CArchive::MapObject

Call this member function to place objects in the map that are not really serialized to the file, but that are available for subobjects to reference.

void MapObject(const CObject* pOb);

Parameters

pOb
A constant pointer to the object being stored.

Remarks

For example, you might not serialize a document, but you would serialize the items that are part of the document. By calling MapObject, you allow those items, or subobjects, to reference the document. Also, serialized subitems can serialize their m_pDocument back pointer.

You can call MapObject when you store to and load from the CArchive object. MapObject adds the specified object to the internal data structures maintained by the CArchive object during serialization and deserialization, but unlike ReadObject and WriteObject, it does not call serialize on the object.

Example

//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

Set to NULL by default, this pointer to a CDocument can be set to anything the user of the CArchive instance wants.

CDocument* m_pDocument;

Remarks

A common usage of this pointer is to convey additional information about the serialization process to all objects being serialized. This is achieved by initializing the pointer with the document (a CDocument-derived class) that is being serialized, in such a way that objects within the document can access the document if necessary. This pointer is also used by COleClientItem objects during serialization.

The framework sets m_pDocument to the document being serialized when a user issues a File Open or Save command. If you serialize an Object Linking and Embedding (OLE) container document for reasons other than File Open or Save, you must explicitly set m_pDocument. For example, you would do this when serializing a container document to the Clipboard.

Example

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 <<

Stores the indicated object or primitive type to the archive.

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);

Return Value

A CArchive reference that enables multiple insertion operators on a single line.

Remarks

The last two versions above are specifically for storing 64-bit integers.

If you used the IMPLEMENT_SERIAL macro in your class implementation, then the insertion operator overloaded for CObject calls the protected WriteObject. This function, in turn, calls the Serialize function of the class.

The CStringT insertion operator (<<) supports diagnostic dumping and storing to an archive.

Examples

This example demonstrates the use of the CArchive insertion operator << with the int and long types.

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

This example demonstrates the use of the CArchive insertion operator << with the CStringT type.

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

CArchive::operator >>

Loads the indicated object or primitive type from the archive.

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);

Return Value

A CArchive reference that enables multiple extraction operators on a single line.

Remarks

The last two versions above are specifically for loading 64-bit integers.

If you used the IMPLEMENT_SERIAL macro in your class implementation, then the extraction operators overloaded for CObject call the protected ReadObject function (with a nonzero run-time class pointer). This function, in turn, calls the Serialize function of the class.

The CStringT extraction operator (>>) supports loading from an archive.

Examples

This example demonstrates the use of the CArchive extraction operator >> with the int type.

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

This example demonstrates the use of the CArchive insertion and extraction operators << and >> with the CStringT type.

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

CArchive::Read

Reads a specified number of bytes from the archive.

UINT Read(void* lpBuf, UINT nMax);

Parameters

lpBuf
A pointer to a user-supplied buffer that is to receive the data read from the archive.

nMax
An unsigned integer specifying the number of bytes to be read from the archive.

Return Value

An unsigned integer containing the number of bytes actually read. If the return value is less than the number requested, the end of file has been reached. No exception is thrown on the end-of-file condition.

Remarks

The archive does not interpret the bytes.

You can use the Read member function within your Serialize function for reading ordinary structures that are contained in your objects.

Example

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

CArchive::ReadClass

Call this member function to read a reference to a class previously stored with WriteClass.

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

Parameters

pClassRefRequested
A pointer to the CRuntimeClass structure that corresponds to the class reference requested. Can be NULL.

pSchema
A pointer to a schema of the run-time class previously stored.

pObTag
A number that refers to an object's unique tag. Used internally by the implementation of ReadObject. Exposed for advanced programming only; pObTag normally should be NULL.

Return Value

A pointer to the CRuntimeClass structure.

Remarks

If pClassRefRequested is not NULL, ReadClass verifies that the archived class information is compatible with your runtime class. If it is not compatible, ReadClass will throw a CArchiveException.

Your runtime class must use DECLARE_SERIAL and IMPLEMENT_SERIAL; otherwise, ReadClass will throw a CNotSupportedException.

If pSchema is NULL, the schema of the stored class can be retrieved by calling CArchive::GetObjectSchema; otherwise, *pSchema will contain the schema of the run-time class that was previously stored.

You can use SerializeClass instead of ReadClass, which handles both reading and writing of the class reference.

Example

See the example for CArchive::WriteClass.

CArchive::ReadObject

Reads object data from the archive and constructs an object of the appropriate type.

CObject* ReadObject(const CRuntimeClass* pClass);

Parameters

pClass
A constant pointer to the CRuntimeClass structure that corresponds to the object you expect to read.

Return Value

A CObject pointer that must be safely cast to the correct derived class by using CObject::IsKindOf.

Remarks

This function is normally called by the CArchive extraction ( >>) operator overloaded for a CObject pointer. ReadObject, in turn, calls the Serialize function of the archived class.

If you supply a nonzero pClass parameter, which is obtained by the RUNTIME_CLASS macro, then the function verifies the run-time class of the archived object. This assumes you have used the IMPLEMENT_SERIAL macro in the implementation of the class.

Example

See the example for CArchive::WriteObject.

CArchive::ReadString

Call this member function to read text data into a buffer from the file associated with the CArchive object.

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

Parameters

rString
A reference to a CString that will contain the resultant string after it is read from the file associated with the CArchive object.

lpsz
Specifies a pointer to a user-supplied buffer that will receive a null-terminated text string.

nMax
Specifies the maximum number of characters to read. Should be one less than the size of the lpsz buffer.

Return Value

In the version that returns BOOL, TRUE if successful; FALSE otherwise.

In the version that returns an LPTSTR, a pointer to the buffer containing the text data; NULL if end-of-file was reached.

Remarks

In the version of the member function with the nMax parameter, the buffer will hold up to a limit of nMax - 1 characters. Reading is stopped by a carriage return-line feed pair. Trailing newline characters are always removed. A NULL character ('\0') is appended in either case.

CArchive::Read is also available for text-mode input, but it does not terminate on a carriage return-line feed pair.

Example

See the example for CArchive::WriteString.

CArchive::SerializeClass

Call this member function when you want to store and load the version information of a base class.

void SerializeClass(const CRuntimeClass* pClassRef);

Parameters

pClassRef
A pointer to a run-time class object for the base class.

Remarks

SerializeClass reads or writes the reference to a class to the CArchive object, depending on the direction of the CArchive. Use SerializeClass in place of ReadClass and WriteClass as a convenient way to serialize base-class objects; SerializeClass requires less code and fewer parameters.

Like ReadClass, SerializeClass verifies that the archived class information is compatible with your runtime class. If it is not compatible, SerializeClass will throw a CArchiveException.

Your runtime class must use DECLARE_SERIAL and IMPLEMENT_SERIAL; otherwise, SerializeClass will throw a CNotSupportedException.

Use the RUNTIME_CLASS macro to retrieve the value for the pRuntimeClass parameter. The base class must have used the IMPLEMENT_SERIAL macro.

Example

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

Call SetLoadParams when you are going to read a large number of CObject-derived objects from an archive.

void SetLoadParams(UINT nGrowBy = 1024);

Parameters

nGrowBy
The minimum number of element slots to allocate if a size increase is necessary.

Remarks

CArchive uses a load array to resolve references to objects stored in the archive. SetLoadParams allows you to set the size to which the load array grows.

You must not call SetLoadParams after any object is loaded, or after MapObject or ReadObject is called.

Example

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

Call this member function to set the object schema stored in the archive object to nSchema.

void SetObjectSchema(UINT nSchema);

Parameters

nSchema
Specifies the object's schema.

Remarks

The next call to GetObjectSchema will return the value stored in nSchema.

Use SetObjectSchema for advanced versioning; for example, when you want to force a particular version to be read in a Serialize function of a derived class.

Example

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

CArchive::SetStoreParams

Use SetStoreParams when storing a large number of CObject-derived objects in an archive.

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

Parameters

nHashSize
The size of the hash table for interface pointer maps. Should be a prime number.

nBlockSize
Specifies the memory-allocation granularity for extending the parameters. Should be a power of 2 for the best performance.

Remarks

SetStoreParams allows you to set the hash table size and the block size of the map used to identify unique objects during the serialization process.

You must not call SetStoreParams after any objects are stored, or after MapObject or WriteObject is called.

Example

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

Writes a specified number of bytes to the archive.

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

Parameters

lpBuf
A pointer to a user-supplied buffer that contains the data to be written to the archive.

nMax
An integer that specifies the number of bytes to be written to the archive.

Remarks

The archive does not format the bytes.

You can use the Write member function within your Serialize function to write ordinary structures that are contained in your objects.

Example

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

CArchive::WriteClass

Use WriteClass to store the version and class information of a base class during serialization of the derived class.

void WriteClass(const CRuntimeClass* pClassRef);

Parameters

pClassRef
A pointer to the CRuntimeClass structure that corresponds to the class reference requested.

Remarks

WriteClass writes a reference to the CRuntimeClass for the base class to the CArchive. Use CArchive::ReadClass to retrieve the reference.

WriteClass verifies that the archived class information is compatible with your runtime class. If it is not compatible, WriteClass will throw a CArchiveException.

Your runtime class must use DECLARE_SERIAL and IMPLEMENT_SERIAL; otherwise, WriteClass will throw a CNotSupportedException.

You can use SerializeClass instead of WriteClass, which handles both reading and writing of the class reference.

Example

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

Stores the specified CObject to the archive.

void WriteObject(const CObject* pOb);

Parameters

pOb
A constant pointer to the object being stored.

Remarks

This function is normally called by the CArchive insertion ( <<) operator overloaded for CObject. WriteObject, in turn, calls the Serialize function of the archived class.

You must use the IMPLEMENT_SERIAL macro to enable archiving. WriteObject writes the ASCII class name to the archive. This class name is validated later during the load process. A special encoding scheme prevents unnecessary duplication of the class name for multiple objects of the class. This scheme also prevents redundant storage of objects that are targets of more than one pointer.

The exact object encoding method (including the presence of the ASCII class name) is an implementation detail and could change in future versions of the library.

Note

Finish creating, deleting, and updating all your objects before you begin to archive them. Your archive will be corrupted if you mix archiving with object modification.

Example

For a definition of the class CAge, see the example for 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

Use this member function to write data from a buffer to the file associated with the CArchive object.

void WriteString(LPCTSTR lpsz);

Parameters

lpsz
Specifies a pointer to a buffer containing a null-terminated text string.

Remarks

The terminating null character ('\0') is not written to the file; nor is a newline automatically written.

WriteString throws an exception in response to several conditions, including the disk-full condition.

Write is also available, but rather than terminating on a null character, it writes the requested number of bytes to the file.

Example

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);

See also

Hierarchy Chart
CFile Class
CObject Class
CSocket Class
CSocketFile Class