函数跟踪 _AFX_INLINE CArchive& AFXAPI operator<<(CArchive& ar, const CObject* pOb) { ar.WriteObject(pOb); return ar; } void CArchive::WriteObject(const CObject* pOb) { // object can be NULL ASSERT(IsStoring()); // proper direction DWORD nObIndex; ASSERT(sizeof(nObIndex) == 4); ASSERT(sizeof(wNullTag) == 2); ASSERT(sizeof(wBigObjectTag) == 2); ASSERT(sizeof(wNewClassTag) == 2); // make sure m_pStoreMap is initialized MapObject(NULL); if (pOb == NULL) { // save out null tag to represent NULL pointer *this << wNullTag; } else if ((nObIndex = (DWORD)(*m_pStoreMap)[(void*)pOb]) != 0) // assumes initialized to 0 map { // save out index of already stored object if (nObIndex < wBigObjectTag) *this << (WORD)nObIndex; else { *this << wBigObjectTag; *this << nObIndex; } } else { // write class of object first CRuntimeClass* pClassRef = pOb->GetRuntimeClass(); WriteClass(pClassRef); // enter in stored object table, checking for overflow CheckCount(); (*m_pStoreMap)[(void*)pOb] = (void*)m_nMapCount++; // cause the object to serialize itself ((CObject*)pOb)->Serialize(*this); } } void CArchive::CheckCount() { if (m_nMapCount >= nMaxMapCount) AfxThrowArchiveException(CArchiveException::badIndex, m_strFileName); } _AFX_INLINE CArchive& CArchive::operator<<(WORD w) { if (m_lpBufCur + sizeof(WORD) > m_lpBufMax) Flush(); void CRuntimeClass::Store(CArchive& ar) const // stores a runtime class description { WORD nLen = (WORD)lstrlenA(m_lpszClassName); ar << (WORD)m_wSchema << nLen; ar.Write(m_lpszClassName, nLen*sizeof(char)); } CRuntimeClass* CObject::GetRuntimeClass() const { return RUNTIME_CLASS(CObject); } void CArchive::WriteClass(const CRuntimeClass* pClassRef) { ASSERT(pClassRef != NULL); ASSERT(IsStoring()); // proper direction if (pClassRef->m_wSchema == 0xFFFF) { TRACE1("Warning: Cannot call WriteClass/WriteObject for %hs.\n", pClassRef->m_lpszClassName); AfxThrowNotSupportedException(); } // make sure m_pStoreMap is initialized MapObject(NULL); // write out class id of pOb, with high bit set to indicate // new object follows // ASSUME: initialized to 0 map DWORD nClassIndex; if ((nClassIndex = (DWORD)(*m_pStoreMap)[(void*)pClassRef]) != 0) { // previously seen class, write out the index tagged by high bit if (nClassIndex < wBigObjectTag) *this << (WORD)(wClassTag | nClassIndex); else { *this << wBigObjectTag; *this << (dwBigClassTag | nClassIndex); } } else { // store new class *this << wNewClassTag; pClassRef->Store(*this); // store new class reference in map, checking for overflow CheckCount(); (*m_pStoreMap)[(void*)pClassRef] = (void*)m_nMapCount++; } } #define DECLARE_SERIAL(class_name) _DECLARE_DYNCREATE(class_name) AFX_API friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb); #define IMPLEMENT_SERIAL(class_name, base_class_name, wSchema) CObject* PASCAL class_name::CreateObject() { return new class_name; } _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, class_name::CreateObject) AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name)); CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb) { pOb = (class_name*) ar.ReadObject(RUNTIME_CLASS(class_name)); return ar; } struct CFileStatus { CTime m_ctime; // creation date/time of file CTime m_mtime; // last modification date/time of file CTime m_atime; // last access date/time of file LONG m_size; // logical size of file in bytes BYTE m_attribute; // logical OR of CFile::Attribute enum values BYTE _m_padding; // pad the structure to a WORD TCHAR m_szFullName[_MAX_PATH]; // absolute path name #ifdef _DEBUG void Dump(CDumpContext& dc) const; #endif }; class CTimeSpan { public: // Constructors CTimeSpan(); CTimeSpan(time_t time); CTimeSpan(LONG lDays, int nHours, int nMins, int nSecs); CTimeSpan(const CTimeSpan& timeSpanSrc); const CTimeSpan& operator=(const CTimeSpan& timeSpanSrc); // Attributes // extract parts LONG GetDays() const; // total # of days LONG GetTotalHours() const; int GetHours() const; LONG GetTotalMinutes() const; int GetMinutes() const; LONG GetTotalSeconds() const; int GetSeconds() const; // Operations // time math CTimeSpan operator-(CTimeSpan timeSpan) const; CTimeSpan operator+(CTimeSpan timeSpan) const; const CTimeSpan& operator+=(CTimeSpan timeSpan); const CTimeSpan& operator-=(CTimeSpan timeSpan); BOOL operator==(CTimeSpan timeSpan) const; BOOL operator!=(CTimeSpan timeSpan) const; BOOL operator<(CTimeSpan timeSpan) const; BOOL operator>(CTimeSpan timeSpan) const; BOOL operator<=(CTimeSpan timeSpan) const; BOOL operator>=(CTimeSpan timeSpan) const; #ifdef _UNICODE // for compatibility with MFC 3.x CString Format(LPCSTR pFormat) const; #endif CString Format(LPCTSTR pFormat) const; CString Format(UINT nID) const; // serialization #ifdef _DEBUG friend CDumpContext& AFXAPI operator<<(CDumpContext& dc,CTimeSpan timeSpan); #endif friend CArchive& AFXAPI operator<<(CArchive& ar, CTimeSpan timeSpan); friend CArchive& AFXAPI operator>>(CArchive& ar, CTimeSpan& rtimeSpan); private: time_t m_timeSpan; friend class CTime; }; class CFile : public CObject { DECLARE_DYNAMIC(CFile) public: // Flag values enum OpenFlags { modeRead = 0x0000, modeWrite = 0x0001, modeReadWrite = 0x0002, shareCompat = 0x0000, shareExclusive = 0x0010, shareDenyWrite = 0x0020, shareDenyRead = 0x0030, shareDenyNone = 0x0040, modeNoInherit = 0x0080, modeCreate = 0x1000, modeNoTruncate = 0x2000, typeText = 0x4000, // typeText and typeBinary are used in typeBinary = (int)0x8000 // derived classes only }; enum Attribute { normal = 0x00, readOnly = 0x01, hidden = 0x02, system = 0x04, volume = 0x08, directory = 0x10, archive = 0x20 }; enum SeekPosition { begin = 0x0, current = 0x1, end = 0x2 }; enum { hFileNull = -1 }; // Constructors CFile(); CFile(int hFile); CFile(LPCTSTR lpszFileName, UINT nOpenFlags); // Attributes UINT m_hFile; operator HFILE() const; virtual DWORD GetPosition() const; BOOL GetStatus(CFileStatus& rStatus) const; virtual CString GetFileName() const; virtual CString GetFileTitle() const; virtual CString GetFilePath() const; virtual void SetFilePath(LPCTSTR lpszNewName); // Operations virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL); static void PASCAL Rename(LPCTSTR lpszOldName, LPCTSTR lpszNewName); static void PASCAL Remove(LPCTSTR lpszFileName); static BOOL PASCAL GetStatus(LPCTSTR lpszFileName, CFileStatus& rStatus); static void PASCAL SetStatus(LPCTSTR lpszFileName, const CFileStatus& status); DWORD SeekToEnd(); void SeekToBegin(); // backward compatible ReadHuge and WriteHuge DWORD ReadHuge(void* lpBuffer, DWORD dwCount); void WriteHuge(const void* lpBuffer, DWORD dwCount); // Overridables virtual CFile* Duplicate() const; virtual LONG Seek(LONG lOff, UINT nFrom); virtual void SetLength(DWORD dwNewLen); virtual DWORD GetLength() const; virtual UINT Read(void* lpBuf, UINT nCount); virtual void Write(const void* lpBuf, UINT nCount); virtual void LockRange(DWORD dwPos, DWORD dwCount); virtual void UnlockRange(DWORD dwPos, DWORD dwCount); virtual void Abort(); virtual void Flush(); virtual void Close(); // Implementation public: virtual ~CFile(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif enum BufferCommand { bufferRead, bufferWrite, bufferCommit, bufferCheck }; virtual UINT GetBufferPtr(UINT nCommand, UINT nCount = 0, void** ppBufStart = NULL, void** ppBufMax = NULL); protected: BOOL m_bCloseOnDelete; CString m_strFileName; }; class CArchive { public: // Flag values enum Mode { store = 0, load = 1, bNoFlushOnDelete = 2, bNoByteSwap = 4 }; CArchive(CFile* pFile, UINT nMode, int nBufSize = 4096, void* lpBuf = NULL); ~CArchive(); // Attributes BOOL IsLoading() const; BOOL IsStoring() const; BOOL IsByteSwapping() const; BOOL IsBufferEmpty() const; CFile* GetFile() const; UINT GetObjectSchema(); // only valid when reading a CObject* void SetObjectSchema(UINT nSchema); // pointer to document being serialized -- must set to serialize // COleClientItems in a document! CDocument* m_pDocument; // Operations UINT Read(void* lpBuf, UINT nMax); void Write(const void* lpBuf, UINT nMax); void Flush(); void Close(); void Abort(); // close and shutdown without exceptions // reading and writing strings void WriteString(LPCTSTR lpsz); LPTSTR ReadString(LPTSTR lpsz, UINT nMax); BOOL ReadString(CString& rString); public: // Object I/O is pointer based to avoid added construction overhead. // Use the Serialize member function directly for embedded objects. friend CArchive& AFXAPI operator<<(CArchive& ar, const CObject* pOb); friend CArchive& AFXAPI operator>>(CArchive& ar, CObject*& pOb); friend CArchive& AFXAPI operator>>(CArchive& ar, const CObject*& pOb); // insertion operations 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<<(unsigned u); // extraction operations CArchive& operator>>(BYTE& by); CArchive& operator>>(WORD& w); CArchive& operator>>(DWORD& dw); CArchive& operator>>(LONG& l); CArchive& operator>>(float& f); CArchive& operator>>(double& d); CArchive& operator>>(int& i); CArchive& operator>>(short& w); CArchive& operator>>(char& ch); CArchive& operator>>(unsigned& u); // object read/write CObject* ReadObject(const CRuntimeClass* pClass); void WriteObject(const CObject* pOb); // advanced object mapping (used for forced references) void MapObject(const CObject* pOb); // advanced versioning support void WriteClass(const CRuntimeClass* pClassRef); CRuntimeClass* ReadClass(const CRuntimeClass* pClassRefRequested = NULL, UINT* pSchema = NULL, DWORD* pObTag = NULL); void SerializeClass(const CRuntimeClass* pClassRef); // advanced operations (used when storing/loading many objects) void SetStoreParams(UINT nHashSize = 2053, UINT nBlockSize = 128); void SetLoadParams(UINT nGrowBy = 1024); // Implementation public: BOOL m_bForceFlat; // for COleClientItem implementation (default TRUE) BOOL m_bDirectBuffer; // TRUE if m_pFile supports direct buffering void FillBuffer(UINT nBytesNeeded); void CheckCount(); // throw exception if m_nMapCount is too large // special functions for reading and writing (16-bit compatible) counts DWORD ReadCount(); void WriteCount(DWORD dwCount); // public for advanced use UINT m_nObjectSchema; CString m_strFileName; protected: // archive objects cannot be copied or assigned CArchive(const CArchive& arSrc); void operator=(const CArchive& arSrc); BOOL m_nMode; BOOL m_bUserBuf; int m_nBufSize; CFile* m_pFile; BYTE* m_lpBufCur; BYTE* m_lpBufMax; BYTE* m_lpBufStart; // array/map for CObject* and CRuntimeClass* load/store UINT m_nMapCount; union { CPtrArray* m_pLoadArray; CMapPtrToPtr* m_pStoreMap; }; // map to keep track of mismatched schemas CMapPtrToPtr* m_pSchemaMap; // advanced parameters (controls performance with large archives) UINT m_nGrowSize; UINT m_nHashSize; };
源代码
// MFCSerial.cpp : Defines the entry point for the console application. // #include "stdafx.h" void Store(){ CFile file; if(!file.Open("c:/Serial.dat",CFile::modeCreate|CFile::modeWrite)){ printf("文件打开失败"); return ; } CArchive archive(&file,CArchive::store); archive<<100<<12.25<<"Hello CArchive"; archive.Close(); file.Close(); } void Load(){ CFile file; if(!file.Open("c:/Serial.dat",CFile::modeRead)){ printf("文件读取失败!"); return ; } CArchive ar(&file,CArchive::load); int num=0; double dou=0.0; CString cStr; ar>>num>>dou>>cStr; printf("%d,%lf,%s\n",num,dou,cStr); ar.Close(); file.Close(); } void CFileSerial(){ } int main(int argc, char* argv[]) { // Store(); Load(); return 0; }
// MFCObjectSerial.cpp : Defines the entry point for the console application. // #include "stdafx.h" class CStudent:public CObject{ public: CStudent(); CStudent(CString m_sName,UINT m_iAge); virtual void Serialize(CArchive& ar); void Show(); public: CString m_sName; UINT m_iAge; //DECLARE_SERIAL(CStudent) _DECLARE_DYNCREATE(CStudent) AFX_API friend CArchive& AFXAPI operator>> (CArchive& ar, CStudent* &pOb); }; // // // IMPLEMENT_SERIAL(CStudent,CObject,1) // CObject* PASCAL CStudent::CreateObject(){ return new CStudent; } // _IMPLEMENT_RUNTIMECLASS(CStudent, CObject, 1, CStudent::CreateObject) AFX_DATADEF CRuntimeClass CStudent::classCStudent = { "CStudent", sizeof(class CStudent), 1, CStudent::CreateObject, RUNTIME_CLASS(CObject), NULL }; CRuntimeClass* CStudent::GetRuntimeClass() const { return RUNTIME_CLASS(CStudent); } AFX_CLASSINIT _init_CStudent(RUNTIME_CLASS(CStudent)); CArchive& AFXAPI operator>>(CArchive& ar, CStudent* &pOb){ pOb = (CStudent*) ar.ReadObject(RUNTIME_CLASS(CStudent)); return ar; } // CStudent::CStudent(){} CStudent::CStudent(CString m_sName,UINT m_iAge){ this->m_sName=m_sName; this->m_iAge=m_iAge; } void CStudent::Serialize(CArchive& ar){ CObject::Serialize(ar); if(ar.IsStoring()){ ar<<m_sName<<m_iAge; }else{ ar>>m_sName>>m_iAge; } } void CStudent::Show(){ printf("学生姓名:%s\n学生年龄:%d\n",m_sName,m_iAge); } // void ObjStore(CStudent &stu){ CFile file; if(!file.Open("c:/stu.dat",CFile::modeCreate|CFile::modeReadWrite)){ printf("文件创建失败!\n"); return; } CArchive ar(&file,CArchive::store); ar<<&stu; ar.Close(); file.Close(); } void ObjLoad(){ CFile file; if(!file.Open("c:/stu.dat",CFile::modeRead)){ printf("文件打开失败!\n"); return ; } CArchive ar(&file,CArchive::load); CStudent *stu=NULL; ar>>stu; //封装反序列化全部过程 ar.Close(); file.Close(); if(stu){ stu->Show(); } } int main(int argc, char* argv[]) { CStudent stu("aaa",20); // ObjStore(stu); ObjLoad(); return 0; }
原文地址:http://blog.csdn.net/u011185633/article/details/44907349