15結(jié)構(gòu)化存儲_第1頁
15結(jié)構(gòu)化存儲_第2頁
15結(jié)構(gòu)化存儲_第3頁
15結(jié)構(gòu)化存儲_第4頁
15結(jié)構(gòu)化存儲_第5頁
已閱讀5頁,還剩19頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、十五. 結(jié)構(gòu)化存儲概念從文件系統(tǒng)到結(jié)構(gòu)化存儲存儲對象和流對象結(jié)構(gòu)化存儲特性復(fù)合文檔 結(jié)構(gòu)化存儲的實現(xiàn)LockBytes對象.創(chuàng)建基于內(nèi)存的復(fù)合文檔創(chuàng)建基于文件的復(fù)合文檔打開復(fù)合文檔復(fù)合文檔的CLSID永久對象例子: MFC實現(xiàn)永久對象例子:復(fù)合文檔11 概念1.1 文件系統(tǒng) 在操作系統(tǒng)誕生之前,應(yīng)用程序處理底層的存儲設(shè)備。 操作系統(tǒng)引入了文件系統(tǒng)。把應(yīng)用系統(tǒng)和底層的存儲設(shè)備區(qū)分開來。多個應(yīng)用可以同時使用一個存儲設(shè)備。操作系統(tǒng)為應(yīng)用程序提供了抽象的流式的存儲結(jié)構(gòu)。 文件系統(tǒng)把存儲設(shè)備按照樹狀結(jié)構(gòu)重新組織起來。如UNIX的文件系統(tǒng),Windows文件系統(tǒng)。目錄,文件。 目錄是文件的容器。文件的數(shù)據(jù)

2、可以存儲在不連續(xù)的存儲區(qū)域。文件系統(tǒng)會管理這些區(qū)域。 操作系統(tǒng)提供了一組系統(tǒng)調(diào)用(Unix)或系統(tǒng)API(Windows)給應(yīng)用系統(tǒng)。應(yīng)用系統(tǒng)通過系統(tǒng)調(diào)用或API來操作文件,從而操作存儲設(shè)備。 應(yīng)用系統(tǒng)使用文件描述符(Unix)或文件句柄(Windows)來代表打開的文件。多個進(jìn)程可以同時訪問一個文件。這些進(jìn)程需要采用同步機制來保證操作的一致性。事實上,這種處理很困難。2結(jié)構(gòu)化存儲把文件系統(tǒng)的概念引入到文件內(nèi)部。從而在存儲結(jié)構(gòu)上支持多應(yīng)用程序的并發(fā)訪問。主要思想:在文件內(nèi)部構(gòu)造一個樹狀層次結(jié)構(gòu)。由存儲對象和流對象構(gòu)成。根節(jié)點為根存儲,根存儲下面可以有子存儲或流對象。子存儲下面可以再有子存儲或流

3、對象。存儲對象本身不包含信息,它是子存儲和流對象的容器。流對象是葉子節(jié)點,是數(shù)據(jù)的載體。這種結(jié)構(gòu)稱為文件內(nèi)部的文件系統(tǒng),這樣的文件稱為復(fù)合文檔。Word Excel PowerPoint Visio 等文件都是復(fù)合文檔。結(jié)構(gòu)化存儲使得多用戶方便地并發(fā)訪問一個文件。各個應(yīng)用訪問屬于自己的存儲對象。 部分訪問。增量訪問。1.2 從文件系統(tǒng)到結(jié)構(gòu)化存儲31.3 存儲對象和流對象COM庫提供了結(jié)構(gòu)化存儲的實現(xiàn),它提供了一組接口和API函數(shù),應(yīng)用程序利用這些接口和函數(shù)來完成結(jié)構(gòu)化存儲操作。結(jié)構(gòu)化存儲定義的存儲對象和流對象由COM庫實現(xiàn),應(yīng)用程序不需要實現(xiàn)這兩個對象。流對象實現(xiàn)了IStream接口: cl

4、ass IStream:public IUnknown (P207) Read, Write, Seek,CopyTo Commit 把所有變化提交到包容該流對象的存儲對象。 Revert rollback取消上次提交以來的所有操作。針對事務(wù)模式的流 存儲對象實現(xiàn)了 IStorage接口: class IStorage:public IUnknown (P208) CreateStream OpenStream 操作子流對象返回IStream接口指針 CreateStorage OpenStorage 操作子存儲對象,返回IStorage接口指針 EnumElements 枚舉所有的子流對象和

5、子存儲對象。 commit Revert。針對事務(wù)模式的存儲。 Stat 獲取存儲對象的信息。41.4 結(jié)構(gòu)化存儲特性1.4.1 訪問模式 創(chuàng)建 臨時存儲 直接模式和事務(wù)模式 優(yōu)先 讀、寫權(quán)限 共享權(quán)限51.4.2 事務(wù)機制創(chuàng)建、打開存儲和流時可以指定事務(wù)模式。只有Commit后,所有的變化才提交到上級。revert可以恢復(fù)到上次commit以來的狀態(tài)。根存儲上commit則會寫到磁盤。revert會恢復(fù)創(chuàng)建、刪除、修改子對象到原先的狀態(tài)。事務(wù)可以嵌套。事務(wù)的嵌套以嵌套標(biāo)志為基礎(chǔ)而不完全取決與層次結(jié)構(gòu)。(中間層次可能不使用事務(wù))事務(wù)針對寫模式而不是讀模式事務(wù)的實現(xiàn)是在內(nèi)存中或臨時文件中保存文件

6、拷貝的方式。所以消耗資源。在直接模式下,revert操作沒有意義,commit操作僅僅對根存儲相當(dāng)于flush操作。在此模式下,我們不能假設(shè)所有的操作會馬上影響到文件系統(tǒng),修改有可能被緩存61.4.3 增量訪問減少保存和打開文件減少操作時間。必要時才訪問。降低了系統(tǒng)對資源的要求。1.4.4 注意事項:必須從根存儲出發(fā)使用Open*或Create*逐個訪問才能到達(dá)底層。文件碎片。(調(diào)用根存儲CopyTo解決)72 復(fù)合文檔 結(jié)構(gòu)化存儲的實現(xiàn)2.1 LockBytes對象.實現(xiàn)結(jié)構(gòu)化存儲:根存儲與底層的存儲介質(zhì)結(jié)合實現(xiàn)存儲對象和流對象。復(fù)合文檔(Compound Document)提供 “Lock

7、Bytes”對象來實現(xiàn)根存儲與底層介質(zhì)的聯(lián)系。底層介質(zhì)可以是磁盤文件、內(nèi)存或用戶自定義的虛擬空間。LockBytes對象是所有存儲介質(zhì)的一種抽象的表達(dá)方式。存儲介質(zhì)描述稱為一般化的字節(jié)流,LockBytes對象負(fù)責(zé)從字節(jié)流中讀寫字節(jié)。 LockBytes對象實現(xiàn)了ILockBytes接口以提供基本的讀寫操作。8COM庫提供了缺省的基于文件句柄的LockBytes對象??衫么藢ο蠼?fù)合文件。COM提供了基于內(nèi)存的LockBytes對象,可利用此對象建立基于內(nèi)存的復(fù)合文檔。 COM允許應(yīng)用系統(tǒng)實現(xiàn)自定義的LockBytes對象,并建立復(fù)合文檔。 文件、內(nèi)存、任何可以抽象稱為字節(jié)序列的存儲設(shè)備都

8、可以作為復(fù)合文檔的載體。不同的載體可以使用統(tǒng)一的存儲結(jié)構(gòu),使用同樣的存儲對象和流對象。9復(fù)合文檔的模型LockBytesrootDisk其他Memory102.2 創(chuàng)建基于內(nèi)存的復(fù)合文檔從內(nèi)存句柄中創(chuàng)建內(nèi)存LockBytes對象:HGLOBAL GlobalAlloc( UINT uFlags, / 分配屬性 SIZE_T dwBytes /字節(jié)數(shù)); 分配內(nèi)存并返回內(nèi)存句柄然后使用:WINOLEAPI CreateILockBytesOnHGlobal ( HGLOBAL hGlobal, /內(nèi)存句柄 BOOL fDeleteOnRelease, LPLOCKBYTES FAR* pplkb

9、yt); /返回指針創(chuàng)建一個基于指定的LockBytes對象創(chuàng)建一個復(fù)合文檔。WINOLEAPI StgCreateDoc( ILockBytes FAR *plkbyt,/ 底層LockBytes對象 DWORD grfMode, /訪問模式 DWORD reserved, IStorage * *ppstgOpen); /返回指針11使用缺省的基于文件句柄的LockBytes對象創(chuàng)建一個復(fù)合文檔。WINOLEAPI StgCreateDocfile( const OLECHAR FAR* pwcsName, /復(fù)合文檔路徑 DWORD grfMode, /訪問模式 DWORD reserv

10、ed, IStorage * *ppstgOpen);/返回指針2.3 創(chuàng)建基于文件的復(fù)合文檔122.4.1 打開文件復(fù)合文檔:WINOLEAPI StgOpenStorage( const OLECHAR FAR* pwcsName, /復(fù)合文檔路徑 IStorage FAR *pstgPriority, /原先打開的復(fù)合文檔 DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage FAR * FAR *ppstgOpen); /返回指針 2.4.2 打開內(nèi)存復(fù)合文檔:WINOLEAPI StgOpenStorageOnILockByt

11、es( ILockBytes FAR *plkbyt, / 底層LockBytes對象 IStorage FAR *pstgPriority, /原先打開的復(fù)合文檔 DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage FAR * FAR *ppstgOpen); /返回指針2.4 打開復(fù)合文檔133 復(fù)合文檔的CLSIDWindows平臺上,文件與應(yīng)用程序相關(guān)聯(lián)Assosiation 1.通過后綴 Windows系統(tǒng)注冊表記錄了文件擴展名和ProgID之間的聯(lián)系。而ProgID最終是與CLSID聯(lián)系在一起,從而確定可執(zhí)行應(yīng)用程序的。

12、手工操作方式:資源管理器工具文件夾選項文件類型 可以查看、修改、增加文件的Assosiation特性。也可以在注冊表中操作。2。如果后綴沒有匹配的,操作系統(tǒng)會看文件是否是復(fù)合文檔,(StgIsStorageFile函數(shù) 見p221),如果不是則要求手工選取可執(zhí)行應(yīng)用程序。如果是,則會讀取文檔的相關(guān)聯(lián)的CLSID。 WriteClassStg和ReadClassStg完成存儲對象的關(guān)聯(lián)CLSID的設(shè)置和獲取工作。存儲對象的一個子流對象“x01CompObj”存儲CLSID。以上函數(shù)封裝了IStorage:SetClass和IStorage:Stat成員函數(shù)。 WriteClassStm和Read

13、ClassStm完成流對象的關(guān)聯(lián)CLSID的設(shè)置和獲取工作注意存儲對象、流對象的CLSID不是這兩個COM對象的CLSID而是,它們相關(guān)聯(lián)的可執(zhí)行應(yīng)用程序的CLSID。 144 永久對象概念上,永久對象與存儲對象和流對象其實沒有任何聯(lián)系。它只不過是一個COM對象,之所以稱為永久對象,是因為它有永久的狀態(tài),它可以把狀態(tài)信息存儲下來,以后可以重建這樣的對象,并且恢復(fù)到以前的狀態(tài)。它之所以跟存儲對象和流對象在實際操作中有密切的聯(lián)系,那是因為,我們很方便地使用COM的結(jié)構(gòu)化存儲機制來保存永久對象的狀態(tài)。其實,我們完全可以不使用結(jié)構(gòu)化存儲而使用別的方式實現(xiàn)永久對象,比如磁盤文件,系統(tǒng)注冊表,目錄服務(wù),數(shù)

14、據(jù)庫服務(wù)等等。但是使用COM的結(jié)構(gòu)化存儲可以使得永久對象實現(xiàn)起來更方便,我們可以利用結(jié)構(gòu)化存儲的優(yōu)良特性。注意我們不能使用基于內(nèi)存的結(jié)構(gòu)化存儲機制來實現(xiàn)永久對象。因為內(nèi)存不是“永久”的。15COM定義了四個常用的永久接口。IPersistStorage, IPersistStream, IPersistStreamInit 和IPersistFile(接口定義見p225)所有的永久接口都包含三個基本的函數(shù)IsDirty Load Save,雖然參數(shù)各不相同,但含義都一樣。Load成員函數(shù)使得永久對象從存儲介質(zhì)中裝入狀態(tài)數(shù)據(jù)。Save成員把狀態(tài)數(shù)據(jù)保存到介質(zhì)中。IsDirty反映了自上次保存后是

15、否被修改,以讓客戶決定是否需要保存。前三個接口使用的結(jié)構(gòu)化存儲機制。后一個接口直接使用文件。165 MFC實現(xiàn)永久對象的例子(p229)1。MFC DLL Automation選項。2。新建一個類CTextObject派生自CCmdTarget,并使之稱為自動化對象。(并沒有必要是自動化對象,只是為了方便而已)3。為自動化對象CTextObject增加屬性Text,類型為VARIANT 實現(xiàn)方式為Get/Set method 注意odl文件的變化,CTextObject類增加了兩個成員函數(shù)GetText 和SetText4。添加內(nèi)部成員變量m_pText 記錄內(nèi)部文本信息。5。添加接口IPer

16、sistStream支持/ 聲明接口嵌套類成員BEGIN_INTERFACE_PART(PersistStream, IPersistStream)STDMETHOD(GetClassID)(LPCLSID);STDMETHOD(IsDirty)();STDMETHOD(Load)(LPSTREAM);STDMETHOD(Save)(LPSTREAM, BOOL);STDMETHOD(GetSizeMax)(ULARGE_INTEGER FAR*);END_INTERFACE_PART(PersistStream)/初始化接口映射表BEGIN_INTERFACE_MAP(CTextObject

17、, CCmdTarget)INTERFACE_PART(CTextObject, IID_IPersistStream, PersistStream)INTERFACE_PART(CTextObject, IID_ITextObject, Dispatch)END_INTERFACE_MAP()永久對象一共實現(xiàn)了兩個接口IDispatch和IPersistStream。176.實現(xiàn)屬性GetText() SetText()7實現(xiàn)接口IPersistStream的成員函數(shù)(IUnknown的函數(shù)) AddRef Release QueryInterfaceSTDMETHODIMP_(ULONG)

18、 CTextObject:XPersistStream:AddRef()METHOD_PROLOGUE(CTextObject, PersistStream) /得到與父類指針的偏移return (ULONG) pThis-ExternalAddRef();8實現(xiàn)接口IPersistStream的成員函數(shù)STDMETHODIMP CTextObject:XPersistStream:GetClassID(LPCLSID lpClassID)METHOD_PROLOGUE(CTextObject, PersistStream)ASSERT_VALID(pThis);*lpClassID = CT

19、extObject:guid; /由DECLARE_OLECREATE定義。供類廠COleClassFactory使用return NOERROR; / 是IPersist的函數(shù)。STDMETHODIMP CTextObject:XPersistStream:IsDirty()METHOD_PROLOGUE(CTextObject, PersistStream)ASSERT_VALID(pThis);return NOERROR; /采取了簡化處理。18STDMETHODIMP CTextObject:XPersistStream:Load(LPSTREAM pStm) ULONG nLeng

20、th; STATSTG statstg;METHOD_PROLOGUE(CTextObject, PersistStream)ASSERT_VALID(pThis);/得到父類指針if(pThis-m_pText != NULL) delete pThis-m_pText;/ 清空原有內(nèi)容VERIFY(pStm-Stat(&statstg, STATFLAG_NONAME) =NOERROR); /得到流的屬性int nSize = statstg.cbSize.LowPart; / assume 0) pThis-m_pText = new charnSize;pStm-Read(pThis

21、-m_pText, nSize, &nLength);/調(diào)用流的Read方法從流中讀取數(shù)據(jù)存到內(nèi)部成員中return NOERROR;此函數(shù)會被用戶調(diào)用,并輸入流指針作為參數(shù)。19STDMETHODIMP CTextObject:XPersistStream:Save(LPSTREAM pStm, BOOL fClearDirty)METHOD_PROLOGUE(CTextObject, PersistStream)ASSERT_VALID(pThis);int nSize = strlen(pThis-m_pText) + 1;pStm-Write(pThis-m_pText, nSize,

22、 NULL);/內(nèi)部數(shù)據(jù)存到流中。return NOERROR;STDMETHODIMP CTextObject:XPersistStream:GetSizeMax(ULARGE_INTEGER FAR* pcbSize)METHOD_PROLOGUE(CTextObject, PersistStream)ASSERT_VALID(pThis);pcbSize-LowPart = strlen(pThis-m_pText) + 1;/返回內(nèi)部數(shù)據(jù)的長度pcbSize-HighPart = 0; / assume Release();22. VERIFY(pStg-CreateStorage(T2COLE(szStorageName), STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pSubStg) = S_OK); /創(chuàng)建子存儲對象 ASSERT(pSubStg != NULL); ReadDirectory(szNewPath, pSubStg);/遞歸調(diào)用 pSubSt

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論