DELPHI基礎(chǔ):COM中的復(fù)合文檔的結(jié)構(gòu)化的存儲(chǔ)

字號(hào):

在永久存儲(chǔ)機(jī)制下,普通文件都是用字節(jié)組織的.每個(gè)文件都是沒有次序的字節(jié)組成的. 而整個(gè)文件則是一塊的形式存儲(chǔ)在磁盤中的,并且每個(gè)塊都是離散的.當(dāng)你要讀某個(gè)文件的時(shí)候文件系統(tǒng)會(huì)管理它的指針并返回要讀取的字節(jié)流.COM采用另一種更為合理的方法來存儲(chǔ)文件和數(shù)據(jù).這種方式就叫結(jié)構(gòu)化存儲(chǔ).結(jié)構(gòu)化存儲(chǔ)采用的辦法是把文件預(yù)先加工后存儲(chǔ)在一個(gè)文檔結(jié)構(gòu)中.這里要使用兩個(gè)COM對(duì)象.storages和streams.storage對(duì)象很類似與文件系統(tǒng)中的目錄,它可以包含其它的storage對(duì)象和stream對(duì)象.你可以把 stream對(duì)象理解成文件系統(tǒng)中的文件.和文件一樣,stream對(duì)象包含數(shù)據(jù),stored 則象一個(gè)連續(xù)的字節(jié)塊.每一個(gè)復(fù)合文檔都包含以上兩個(gè)對(duì)象.COM通過兩個(gè)借口來訪問上面兩個(gè)對(duì)象IStorage和IStream.
    為什么我們需要結(jié)構(gòu)化存儲(chǔ)? 是的,要知道你的復(fù)合文檔中包括,圖象,文字,等等其它一些數(shù)據(jù).好啦,現(xiàn)在你大概希望把它們放到一起去.以前的做法是當(dāng)你要保存文件的時(shí)候,文件系統(tǒng)會(huì)把原文件重寫從而把你的新的資料加入進(jìn)來.聽上去很花時(shí)間和精力是嗎?是的,所結(jié)構(gòu)化處理采用另外一個(gè)辦法.新的數(shù)據(jù)存儲(chǔ)到老的數(shù)據(jù)后面.是的就想文件系統(tǒng)那樣存放到新的文件夾那樣所不同的是它使用的是storage對(duì)象和stream對(duì)象.下面看看它給我們帶來了什么好處
    1.結(jié)構(gòu)化存儲(chǔ)能夠讓你完全控制每一個(gè)獨(dú)立的對(duì)象,每次讀/寫你不必去讀寫整個(gè)文件,而可以讀/寫你想要的段落.
    2.并且一個(gè)用戶可以并發(fā)的讀/寫同一個(gè)文件,復(fù)合文檔:就是把不同類型的數(shù)據(jù)存儲(chǔ)在一個(gè)文件中.如一個(gè)word文件可以包括excel的圖表,圖象表格,或者其它數(shù)據(jù).,現(xiàn)在讓我們來看它的兩個(gè)接口IStorage 接口,//考試大編注。
    如你所想的那樣它就象文件系統(tǒng)中的目錄.
    IStream 接口
    它用來讀/寫數(shù)據(jù)到stream對(duì)象.
    你可以到MSDN上查找到相應(yīng)的文檔.
    最后讓我們舉個(gè)例子,來看看他們是如何工作的.
    步驟如下:
    1.首先要調(diào)用StgCreateDocfile函數(shù)來創(chuàng)建一個(gè)存儲(chǔ)根對(duì)象.我們的復(fù)合文件要 存儲(chǔ)每一個(gè)存儲(chǔ)對(duì)象和流對(duì)象.StgCreateDocfile函數(shù)返回一個(gè)IStorage接口指針
    2.調(diào)用IStorage的CreateStream來創(chuàng)建一個(gè)流對(duì)象.該函數(shù)返回一個(gè)IStream的指針
    3.最后調(diào)用IStream的wirte函數(shù)來寫如流.
    源代碼如下:
    #include
    int main(int argc, char* argv[])
    {
    CoInitialize(NULL);
    IStorage* pStr;
    HRESULT hr = StgCreateDocfile( L\"test.mcb\", STGM_DIRECT|STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, &pStr);
    IStream* pStream;
    hr = pStr->CreateStream( L\"mcbStream\", STGM_DIRECT|STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &pStream );
    ULONG name;
    char data[] = \"Mahesh testing \" ;
    pStream->Write( data, strlen(data), &name ) ;
    CoUninitialize();
    return 0;
    }