按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
char* pBuffer = new char'0x1000';
CFile file(〃mydoc。doc〃; CFile::modeReadWrite);
DWORD dwBytesRemaining = file。GetLength();
UINT nBytesRead;
DWORD dwPosition;
while (dwBytesRemaining) {
dwPosition = file。GetPosition();
nBytesRead = file。Read(pBuffer; 0x1000);
::CharLowerBuff(pBuffer; nBytesRead);
file。Seek((LONG)dwPosition; CFile::begin);
file。Write(pBuffer; nBytesRead);
dwBytesRemaining …= nBytesRead;
}
delete'' pBuffer;
文件的操作常需配合对异常情况(exception )的处理,因为文件的异常情况特别多:档
案找不到啦、文件handles 不足啦、读写失败啦。。。。上一例加入异样情况处理后如下:
char* pBuffer = new char'0x1000';
try {
CFile file(〃mydoc。doc〃; CFile::modeReadWrite);
DWORD dwBytesRemaining = file。GetLength();
UINT nBytesRead;
DWORD dwPosition;
while (dwBytesRemaining) {
dwPosition = file。GetPosition();
nBytesRead = file。Read(pBuffer; 0x1000);
::CharLowerBuff(pBuffer; nBytesRead);
file。Seek((LONG)dwPosition; CFile::begin);
file。Write(pBuffer; nBytesRead);
dwBytesRemaining …= nBytesRead;
}
}
catch (CFileException* e) {
if (e…》cause == CFileException::fileNoteFound)
MessageBox(〃File not found〃);
else if (e…》cause == CFileException::tooManyOpeFiles)
MessageBox(〃File handles not enough〃);
else if (e…》cause == CFileException::hardIO)
500
…………………………………………………………Page 563……………………………………………………………
第8章 Document…View 深入探討
MessageBox(〃Hardware error〃);
else if (e…》cause == CFileException::diskFull)
MessageBox(〃Disk full〃);
else if (e…》cause == CFileException::badPath)
MessageBox(〃All or part of the path is invalid〃);
else
MessageBox(〃Unknown file error〃);
e…》Delete();
}
delete'' pByffer;
台面上的Serialize 动作
让我以Scribble 为例,向你解释台面上的(应用程序代码中可见的)serialization 动作。根
据图8…3 的数据结构,Scribble 程序的文件读写动作是这么分工的:
Framework 调用CSribbleDoc::Serialize,用以对付文件。
CScribbleDoc 再往下调用CStroke::Serialize,用以对付线条。
CStroke 再往下调用CArray::Serialize,用以对付点数组。
读也由它,写也由它,究竟Serialize 是读还是写?这一点不必我们操心。Framework 呼
Serialize 时会传来一个CArchive 对象(稍后我会解释CArchive),你可以想象它
代表一个文件,透过其IsStoring 成员函数,即可知道究竟要读还是写。图8…5 是各层
叫
级的Serialize 动作示意图,文字说明已在图片之中。
注意:Scribble 程序使用CArray 储存鼠标位置坐标,而CArray 是
一个template class ,解释起来比较复杂。所以稍后我挖给各位看的Serialize 函数原始
码,采用CDWordArray 的成员函数而非CArray 的成员函数。Visual C++ 1。5 版的
Scribble 范例程序就是使用CDWordArray (彼时还未有template class )。
然而,为求完备,我还是在此先把CArray 的Serialize 函数源代码列出:
template
void AFXAPI SerializeElements (CArchive& ar; TYPE* pElements; int nCount)
{
ASSERT(nCount == 0 ||
501
…………………………………………………………Page 564……………………………………………………………
第篇 深入 MFC 程式設計
AfxIsValidAddress(pElements; nCount * sizeof(TYPE)));
// default is bit…wise read/write
if (ar。IsStoring())
ar。Write ((void*)pElements; nCount * sizeof(TYPE));
else
ar。Read ((void*)pElements; nCount * sizeof(TYPE));
}
template
void CArray::Serialize(CArchive& ar)
{
ASSERT_VALID(this);
CObject::Serialize(ar);
if (ar。IsStoring())
{
ar。WriteCount (m_nSize);
}
else
{
DWORD nOldSize = ar。ReadCount ();
SetSize (nOldSize; …1);
}
SerializeElements (ar; m_pData; m_nSize);
}
void CScribbleDoc::Serialize(CArchive& ar)
2 CObList::Serialize(Carchive& ar)
{ { 。。。 } //源代