码迷,mamicode.com
首页 > 编程语言 > 详细

MFC第九天

时间:2015-04-07 09:53:47      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:cpp   mfc   

MFC文件操作
    1.相关类
    CFile类  封装了文件句柄以及相关操作的API
    CFileFind类   封装了文件查找相关的类
    
    2 CFile类的使用
    2.1打开或者创建文件
    2.2文件读写    通常放到宜昌处理结果中
    2.3关闭文件



CFileFind    
    查找指定目录下的所有文件和文件夹  
    开始查找
    virtual BOOL FindFile( LPCTSTR pstrName = NULL, DWORD dwUnused = 0 );
    查找下一个文件
    virtual BOOL FindNextFile( );
    GetXXX  或者  IsXXX,获取文件信息并判断。
    CFileFind::Close ,结束查找


序列化(串行化)
    方便文件读写,避免类型转换
    将数据以二进制流的方式保存到文件,或者重文件读取.

    相关类
    CFile
    CArchive 归档类,执行具体的数据读写操作。使用该类替换CFile类的Read,Write函数
    写操作“<<”
    读操作“>>”

    序列化的操作步骤
        CFile::Open

        定义CArchive类的对象
        >>或<<,执行读写操作
        关闭CArchive对象

        CFile::Close()

    对象的序列化。
    将对象的所有数据以二进制流写入文件。
    反序列化  从文件先读取类的信息,创建对象,然后读取对象的成员初始化新创建的对象。
    对象的序列化以动态创建为必要条件。

    定义一个支持序列化的类。
        必须是CObject的子类
        添加序列化的声明宏和实现宏
        重写Serialize函数,在函数中序列化对象的成员。

    1,_init_Cstudent  结构体变量,作用是调用AfxClassInfo
    在函数中,获取应用程序的模块信息,将CStudent的运行时信息的地址保存到m_classList链表
    中(m_classList是模块状态信息的成员)。
    2,operator>>  友元函数加载CStudent类的对象

    对象序列化过程。
    序列化
    调用ar.WriteObject()函数
    在函数中,首先调用GetRuntimeClass函数获取CStudent类的运行时信息。
    调用WriteClass函数,将类的信息写入到文件.
    在store函数中依次将类的,版本,长度,名称 写入文件。
    调用Serialize函数,函数中依次将CStudent类的成员变量写入到文件。

    反序列化
    ar.ReadObject
    ReadClass->Load
    Serialize


函数跟踪


	_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;
}


MFC第九天

标签:cpp   mfc   

原文地址:http://blog.csdn.net/u011185633/article/details/44907349

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!