konhon

          忘掉過(guò)去,展望未來(lái)。找回自我,超越自我。
          逃避不一定躲的過(guò), 面對(duì)不一定最難過(guò), 孤單不一定不快樂(lè), 得到不一定能長(zhǎng)久, 失去不一定不再擁有, 可能因?yàn)槟硞€(gè)理由而傷心難過(guò), 但我卻能找個(gè)理由讓自己快樂(lè).

          Google

          BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
            203 Posts :: 0 Stories :: 61 Comments :: 0 Trackbacks

          常用鏈接

          留言簿(7)

          隨筆分類

          隨筆檔案

          相冊(cè)

          Business

          Download

          English

          Erp/Mrp

          HR

          J2me

          Java

          Linux/Unix

          Mobile Telephone

          Oracle

          Other

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          2007年4月4日 #

             很多股民常常感到孤獨(dú)無(wú)助,買入的股票總是被套,這里面折射出一個(gè)問(wèn)題,那就是你沒(méi)有真正的掌握好買入點(diǎn),今天我就在這里給大家講一講如何把握買入點(diǎn)。

            由于股票變化無(wú)常,主力更是絞盡腦汁和散戶斗智斗勇,所以買入法也沒(méi)有固定格式,我在這里只簡(jiǎn)單的介紹幾種很有效的方法,僅供你借鑒。

               1、量縮法。顧名思義,就是當(dāng)股票在一定“趨勢(shì)和條件”下,成交量開(kāi)始萎縮到不能再萎縮時(shí),說(shuō)明下跌能量消耗已盡,此時(shí)就是最好的買入點(diǎn)。所謂的“趨勢(shì)和條件”是講——這只股票運(yùn)行趨勢(shì)必須是在上升通道或低位震蕩中,當(dāng)它連續(xù)下跌兩到三天時(shí),成交量已經(jīng)萎縮很多,股價(jià)波動(dòng)范圍已經(jīng)很小,盤(pán)中也不再見(jiàn)有大的買單,特別是遇到大盤(pán)下跌時(shí),它也不再下跌,這說(shuō)明這只股票到了“谷”底,隨時(shí)有反彈和新的行情發(fā)動(dòng),此時(shí)就是最價(jià)買入點(diǎn)。例如600297在1月30號(hào)到2月2號(hào),連續(xù)下跌了四天,切成交量逐步萎縮,2月2號(hào)就是個(gè)最價(jià)買點(diǎn)。

               2、前高突破法。當(dāng)一只股票經(jīng)過(guò)一段時(shí)間的上漲,之后開(kāi)始進(jìn)入回調(diào),當(dāng)經(jīng)過(guò)一段時(shí)間的調(diào)整,再次開(kāi)始放量攻擊前期高點(diǎn)時(shí),此時(shí)也是買入點(diǎn)。但是這里最難把握的就是主力的假突破,很容易上當(dāng),這需要你自己正確判斷。比方說(shuō)600983在1月23達(dá)到一個(gè)高點(diǎn)后,2月8號(hào)開(kāi)始放量攻擊前期高點(diǎn),那么2月8號(hào)就是最價(jià)買點(diǎn)。而600717在3月8號(hào)就是一個(gè)假突破。我特別強(qiáng)調(diào)一點(diǎn),最好是出現(xiàn)三次沖擊前期高點(diǎn)的股票,把握性最大。

               3、長(zhǎng)陽(yáng)之后等待法。就是當(dāng)某只股票出現(xiàn)長(zhǎng)陽(yáng)甚至是漲停時(shí),第二天它很可能不再連續(xù)拉升,而是出現(xiàn)小幅的調(diào)整,此時(shí)也是買入點(diǎn),例如600723在1月18日就是一個(gè)買入點(diǎn)。

               4、誘空識(shí)破法。很多主力在進(jìn)入下一波的大行情中,往往做最后的誘空洗盤(pán)。此時(shí)也是最價(jià)買入法,這需要你高超的識(shí)盤(pán)技巧。例如,600176在1月31號(hào),出現(xiàn)了一條放量的長(zhǎng)陰,其實(shí)那是誘空,做出這樣的判斷是要對(duì)這只股票的基本面和技術(shù)面都非常熟悉才行。

               5、大換手率的等待法。當(dāng)某只股票在低位(特別強(qiáng)調(diào)是低位)出現(xiàn)大換手率時(shí),說(shuō)明主力殺入,你隨時(shí)可以跟進(jìn)。例如600178在1月19和22連續(xù)兩天出現(xiàn)超過(guò)12%的還手率,之后再出現(xiàn)低點(diǎn)時(shí),你就可以殺入了。
          posted @ 2007-04-04 06:52 konhon 優(yōu)華 閱讀(1437) | 評(píng)論 (0)編輯 收藏

          2007年3月29日 #

          http://www.openitpower.com/wenzhang/97/10846_1.html

            與TTable、TQuery一樣,TClientDataSet也是從TDataSet繼承下來(lái)的,它通常用于多層體系結(jié)構(gòu)的客戶端。TClientDataSet最大的特點(diǎn)是它不依賴于BDE(Borland Database Engine),但它需要一個(gè)動(dòng)態(tài)鏈接庫(kù)的支持,這個(gè)動(dòng)態(tài)鏈接庫(kù)叫DBCLIENT.DLL。在客戶端,也不需要用TDatabase構(gòu)件,因?yàn)榭蛻舳瞬⒉恢苯舆B接數(shù)據(jù)庫(kù)。
            由于TClientDataSet是從TDataSet繼承下來(lái)的,所以,它支持諸如編輯、搜索、瀏覽、糾錯(cuò)、過(guò)濾等功能。由于TClientDataSet在內(nèi)存中建立了數(shù)據(jù)的本地副本,上述操作的執(zhí)行速度很快。也正是由于TClientDataSet并不直接連接數(shù)據(jù)庫(kù),因此,客戶程序必須提供獲取數(shù)據(jù)的機(jī)制。在Delphi 4中,TClientDataSet有三種途徑獲取數(shù)據(jù):
          .從文件中存取數(shù)據(jù)。
          .從本地的另一個(gè)數(shù)據(jù)集中獲取數(shù)據(jù)。
          .通過(guò)IProvider接口從遠(yuǎn)程數(shù)據(jù)庫(kù)服務(wù)器獲取數(shù)據(jù)。
            在一個(gè)客戶程序中,可以同時(shí)運(yùn)用上述三種機(jī)制獲取數(shù)據(jù)。
          11.1 瀏覽和編輯數(shù)據(jù)
            和其他數(shù)據(jù)集構(gòu)件一樣,可以用標(biāo)準(zhǔn)的數(shù)據(jù)控件顯示由TClientDataSet引入的數(shù)據(jù)集,當(dāng)然,這需要借助于TDataSource構(gòu)件。
            由于TClientDataSet是從TDataSet繼承下來(lái)的,所以,凡是其他數(shù)據(jù)集構(gòu)件支持的功能,TClientDataSet構(gòu)件也大致具備。不同的是,TClientDataSet能夠在內(nèi)存中建立數(shù)據(jù)的副本,因此,TClientDataSet比其他數(shù)據(jù)集構(gòu)件增加了一些特殊的功能。
          11.1.1 瀏覽數(shù)據(jù)
            可以用標(biāo)準(zhǔn)的數(shù)據(jù)控件顯示由TClientDataSet引入的數(shù)據(jù)集。在運(yùn)行期,可以調(diào)用諸如First、GotoKey、Last、Next和Prior等函數(shù)來(lái)瀏覽數(shù)據(jù)。
            TClientDataSet也支持書(shū)簽功能,可以用書(shū)簽來(lái)標(biāo)記某條記錄,以后就可以方便地找到這條記錄。
            對(duì)于TTable、TQuery等數(shù)據(jù)集構(gòu)件來(lái)說(shuō),只能讀RecNo屬性來(lái)判斷當(dāng)前記錄的序號(hào)。對(duì)于TClientDataSet構(gòu)件來(lái)說(shuō),還可以寫(xiě)RecNo屬性,使某一序號(hào)的記錄成為當(dāng)前記錄。
          11.1.2 CanModify屬性
            TDataSet的CanModify屬性用于判斷數(shù)據(jù)集中的數(shù)據(jù)是否可以修改。CanModify屬性本身是只讀的,也就是說(shuō),數(shù)據(jù)是否能夠修改不取決于應(yīng)用程序。
            不過(guò),TClientDataSet構(gòu)件有其特殊性,因?yàn)門ClientDataSet已經(jīng)把數(shù)據(jù)在內(nèi)存中建立了副本,因此,應(yīng)用程序可以決定是否允許修改數(shù)據(jù)。如果不允許用戶修改數(shù)據(jù),只要把ReadOnly屬性設(shè)為True,此時(shí),CanModify屬性肯定返回False。
            與其他數(shù)據(jù)集構(gòu)件不同,修改TClientDataSet構(gòu)件的ReadOnly屬性時(shí),不需要事先把Active屬性設(shè)為True。
          11.1.3 取消修改
            TClientDataSet傳輸數(shù)據(jù)的基本單位稱為數(shù)據(jù)包,當(dāng)前的數(shù)據(jù)包可以由Data屬性來(lái)訪問(wèn)。不過(guò),用戶對(duì)數(shù)據(jù)的修改并不直接反映到Data屬性中,而是臨時(shí)寫(xiě)到一個(gè)日志即Delta屬性中,這樣做的好處是以后隨時(shí)可以取消修改。
            不過(guò),這里要說(shuō)明一點(diǎn),盡管用戶的修改并沒(méi)有反映到Data,當(dāng)用戶在數(shù)據(jù)控件中看到的卻是最新修改的數(shù)據(jù)。如果一條記錄被反復(fù)修改了多次,用戶看到的只是最新的數(shù)據(jù),但日志中卻記載了多次。
            要取消上一次的修改,調(diào)用UndoLastChange函數(shù)。UndoLastChange需要傳遞一個(gè)布爾類型的參數(shù)叫FollowChange,如果FollowChange參數(shù)設(shè)為True,光標(biāo)就移到被恢復(fù)的記錄上,如果FollowChange參數(shù)設(shè)為False,光標(biāo)仍然在當(dāng)前記錄上。
            ChangeCount屬性返回日志中記載的修改次數(shù)。如果一條記錄被反復(fù)修改了多次,每調(diào)用一次UndoLastChange能夠逐級(jí)取消上一次的修改。
            UndoLastChange只能取消上一次的修改,如果想一下子取消所有的修改,首先要選擇一個(gè)記錄,然后調(diào)用RevertRecord。RevertRecord將從日志中取消所有對(duì)當(dāng)前記錄的修改。
            TClientDataSet還有一個(gè)SavePoint屬性,它能把當(dāng)前的編輯狀態(tài)保存起來(lái),以后隨時(shí)可以返回當(dāng)時(shí)的狀態(tài)。例如,可以這樣保存當(dāng)前的狀態(tài):
            BeforeChanges := ClientDataSet1.SavePoint;
            以后,可以這樣來(lái)恢復(fù)當(dāng)時(shí)的狀態(tài):
            ClientDataSet1.SavePoint := BeforeChanges;
            應(yīng)用程序可以保存多處狀態(tài),可以恢復(fù)其中一個(gè)狀態(tài),不過(guò),一旦某個(gè)狀態(tài)被恢復(fù),在其之后的狀態(tài)就無(wú)效。
            如果要一下子取消日志中記載的所有修改,可以調(diào)用CancelUpdates函數(shù)。CancelUpdates將把日志清空,取消所有的修改。
            如果LogChanges屬性設(shè)為False,用戶對(duì)數(shù)據(jù)的修改就會(huì)直接反映到Data屬性中。
          11.1.4 合并修改
            要把日志中記載的修改合并到Data屬性中,有兩種方式,具體使用哪一種方式,取決于應(yīng)用程序獲取數(shù)據(jù)的機(jī)制。不過(guò),不管是哪種機(jī)制,合并后,日志自動(dòng)被清空。
            對(duì)于一個(gè)從文件中獲取數(shù)據(jù)的程序來(lái)說(shuō),只要調(diào)用MergeChangeLog函數(shù),就把日志中記載的修改合并到Data屬性中。不用擔(dān)心其他用戶同時(shí)修改了數(shù)據(jù)。
            對(duì)于一個(gè)從應(yīng)用服務(wù)器獲取數(shù)據(jù)的程序來(lái)說(shuō),就不能調(diào)用MergeChangeLog來(lái)合并數(shù)據(jù),而要調(diào)用ApplyUpdates函數(shù),ApplyUpdates會(huì)把日志中記載的修改傳遞給應(yīng)用服務(wù)器,待應(yīng)用服務(wù)器成功地把數(shù)據(jù)更新了數(shù)據(jù)庫(kù)服務(wù)器后,才會(huì)合并到Data屬性中。
          11.1.5 糾錯(cuò)
            TClientDataSet支持糾錯(cuò)功能。一般情況下,需要自己建立糾錯(cuò)規(guī)則,以便對(duì)用戶輸入的數(shù)據(jù)進(jìn)行糾錯(cuò)。
            此外,如果獲得了IProvider接口的話,還可以從遠(yuǎn)程服務(wù)器引入糾錯(cuò)規(guī)則。
            有時(shí)候,客戶端可能需要暫時(shí)禁止糾錯(cuò),因?yàn)榭蛻舳藦膽?yīng)用服務(wù)器檢索數(shù)據(jù)是分階段進(jìn)行的,在所有的數(shù)據(jù)檢索完畢之前,有些糾錯(cuò)規(guī)則很可能會(huì)報(bào)錯(cuò)。
          要暫時(shí)禁止糾錯(cuò),可以調(diào)用DisableConstraints,要重新允許糾錯(cuò),可以調(diào)用EnableConstraints函數(shù)。DisableConstraints和EnableConstraints實(shí)際上都是作用于一個(gè)內(nèi)部的計(jì)數(shù)。
          11.2 索 引
            使用索引有這么幾個(gè)好處:
          .在數(shù)據(jù)集中定位記錄比較快。
          .能夠在兩個(gè)數(shù)據(jù)集之間建立Lookup或Master/Detail關(guān)系。
          .可以對(duì)記錄排序。
            在多層體系結(jié)構(gòu)中,當(dāng)客戶程序從應(yīng)用服務(wù)器檢索數(shù)據(jù)時(shí),它同時(shí)獲得了默認(rèn)的索引。默認(rèn)的索引叫DEFAULT_ORDER,可以使用這個(gè)索引排序,但不能修改或刪除這個(gè)索引。
            除了默認(rèn)的索引外,TClientDataSet還對(duì)日志中記載的記錄自動(dòng)建立了一個(gè)副索引叫CHANGEINDEX。與DEFAULT_ORDER一樣,不能修改或刪除這個(gè)副索引。
            另外,還可以使用數(shù)據(jù)集中已建立的其他索引,或者自己建立索引。
          11.2.1 創(chuàng)建一個(gè)新的索引
            要?jiǎng)?chuàng)建一個(gè)新的索引,可以調(diào)用AddIndex。AddIndex需要傳遞若干個(gè)參數(shù):
            一是Name參數(shù),用于指定索引名。在運(yùn)行期切換索引時(shí)需要用到索引的名稱。
            二是Fields參數(shù),它是一個(gè)字符串,用于指定索引中的字段名,彼此之間用分號(hào)隔開(kāi)。
            三是Options參數(shù),用于設(shè)置索引的選項(xiàng),包含ixDescending元素表示按降序排列,包含ixCaseInsensitive元素表示大小寫(xiě)不敏感。
            四是DescFields參數(shù),它也是一個(gè)字符串,用于指定若干個(gè)字段名,這些字段將按照降序排列。
            五是CaseInsFields參數(shù),它的作用與DescFields參數(shù)類似,包含在CaseInsFields參數(shù)中的字段將對(duì)大小寫(xiě)不敏感。
            六是GroupingLevel參數(shù),用于指定分組級(jí)別,其值不能超過(guò)索引中的字段數(shù)。
            下面的代碼創(chuàng)建了一個(gè)索引:
          If Edit1.Text <> '' and ClientDataSet1.Fields.FindField(Edit1.Text) then
          Begin
          ClientDataSet1.AddIndex(Edit1.Text+'Index',Edit1.Text,  
            [ixCaseInsensitive],'','',0);
          ClientDataSet1.IndexName := Edit1.Text + 'Index';
          End;
          為了避免創(chuàng)建一個(gè)索引,可以臨時(shí)用IndexFieldNames屬性來(lái)指定若干個(gè)字段,讓數(shù)據(jù)集按這些字段排序。
          11.2.2 刪除和切換索引
            要?jiǎng)h除一個(gè)先前創(chuàng)建的索引,可以調(diào)用DeleteIndex并指定要?jiǎng)h除的索引名稱。注意:DEFAULT_ORDER和CHANGEINDEX不能刪除。
            如果建立了多個(gè)索引,可以任意選擇其中的一個(gè)索引,這就要用到IndexName屬性。
          11.2.3 用索引把數(shù)據(jù)分組
            選擇了一個(gè)索引后,數(shù)據(jù)集將自動(dòng)按其中的字段進(jìn)行排序。這樣,臨近的記錄往往在關(guān)鍵字段上含有相同的值。例如,假設(shè)有一個(gè)表是這樣的:
          SalesRep Customer OrderNo Amount
          1      1     5    100
          1      1     2    50
          1      2     3    200
          1       2     6    75
          2      1     1    10
          2      3     4    200
            可以看出,SalesRep字段的值有重復(fù)的。對(duì)于SalesRep字段的值為1的來(lái)說(shuō),Customer字段的值也有重復(fù)的。這就是說(shuō),可以按SalesRep字段分組,進(jìn)而再按Customer字段分組。顯然,這里的分組級(jí)別是不同的,按SalesRep字段建立的分組屬于第一級(jí),按Customer字段建立的分組屬于第二級(jí)。實(shí)際上,分組級(jí)別取決于字段在索引中的順序。
            TClientDataSet可以決定是否按照分組級(jí)別來(lái)顯示記錄的值。例如,也許想以下面這種形式顯示數(shù)據(jù):
          SalesRep Customer OrderNo Amount
          1      1    5    100
                     2    50
                 2    3    200
                     6    75
          2      1    1    10
          2      3    4    200
            要判斷當(dāng)前記錄某一級(jí)的什么位置,可以調(diào)用GetGroupState函數(shù)。GetGroupState函數(shù)需要傳遞一個(gè)參數(shù),用于指定分組級(jí)別。
          11.3 計(jì) 算 字 段
            與其他數(shù)據(jù)集一樣,也可以在TClientDataSet建立的數(shù)據(jù)集中增加計(jì)算字段。計(jì)算字段的值是基于同一個(gè)記錄中的其他字段計(jì)算出來(lái)的。
            在其他數(shù)據(jù)集中,只要用戶修改了數(shù)據(jù)或當(dāng)前記錄發(fā)生改變,就會(huì)觸發(fā)OnCalcFields事件,換句話說(shuō),計(jì)算字段的值就被計(jì)算一次。
            TClientDataSet引入了“內(nèi)部計(jì)算字段”的概念。與一般的計(jì)算字段不同的是,內(nèi)部計(jì)算字段的值將隨其他字段的值一起存取,這樣,只有當(dāng)用戶修改了數(shù)據(jù)才會(huì)觸發(fā)OnCalcFields事件,如果僅僅改變了當(dāng)前記錄,不會(huì)觸發(fā)OnCalcFields事件。也就是說(shuō),內(nèi)部計(jì)算字段的值需要重新計(jì)算的機(jī)會(huì)大大減少。
            在處理OnCalcFields事件的句柄中,首先要判斷State屬性。如果State屬性返回dsInternalCalc,此時(shí)需要計(jì)算內(nèi)部計(jì)算字段的值。如果State屬性返回dsCalcFields,此時(shí)需要計(jì)算一般的計(jì)算字段的值。
          11.4 統(tǒng) 計(jì) 值
            TClientDataSet增加了統(tǒng)計(jì)的功能,它可以基于分組自動(dòng)計(jì)算總和、平均、計(jì)數(shù)、最大、最小值。當(dāng)用戶編輯數(shù)據(jù)時(shí),這些統(tǒng)計(jì)值會(huì)自動(dòng)跟著變化。
          11.4.1 指定統(tǒng)計(jì)方式
            要指定怎樣進(jìn)行統(tǒng)計(jì),就要用到Aggregates屬性。這個(gè)屬性是一個(gè)TAggregates對(duì)象,它用于管理一組TAggregate對(duì)象。
            在設(shè)計(jì)期,可以單擊Aggregates屬性邊上的省略號(hào)按鈕打開(kāi)如圖11.1所示
          的編輯器。
            圖11.1 管理一組TAggregate對(duì)象
            單擊按鈕可以增加一個(gè)TAggregate對(duì)象,單擊按鈕可以刪減一個(gè)TAggregate對(duì)象,單擊按鈕可以把TAggregate對(duì)象前移,單擊按鈕可以把TAggregate對(duì)象后移。
            可以用字段編輯器專門創(chuàng)建一個(gè)用于表達(dá)統(tǒng)計(jì)值的字段,該字段的類型必須是“Aggregate”。Delphi 4會(huì)自動(dòng)創(chuàng)建一個(gè)TAggregate對(duì)象,并加到Aggregates屬性中。選擇一個(gè)TAggregate對(duì)象,Object Inpector將顯示該對(duì)象的屬性。
            其中,Expression屬性用于指定統(tǒng)計(jì)表達(dá)式,例如:
          Sum(Field1)
            也可以是比較復(fù)雜的表達(dá)式:
          Sum(Qty * Price) - Sum(AmountPaid)
            在表達(dá)式中,可以使用下列統(tǒng)計(jì)運(yùn)算符:
          .Sum計(jì)算一組數(shù)據(jù)的總和。
          .Avg計(jì)算一組數(shù)據(jù)的平均值。
          .Count計(jì)算一組數(shù)據(jù)中的非空值的個(gè)數(shù)。
          .Min計(jì)算一組數(shù)據(jù)的最小值。
          .Max計(jì)算一組數(shù)據(jù)的最大值。
            除了上述幾個(gè)統(tǒng)計(jì)運(yùn)算符外,還可以使用過(guò)濾條件中所能使用的運(yùn)算符,但不能嵌套。在一個(gè)表達(dá)式中,可以混合出現(xiàn)幾個(gè)統(tǒng)計(jì)值或常量,但不能混合出現(xiàn)統(tǒng)計(jì)值和字段。
            Sum(Qty * Price){合法}
            Max(Field1) - Max(Field2){合法}
            Avg(DiscountRate) * 100{合法}
            Min(Sum(Field1)){非法,不能嵌套}
            Count(Field1) - Field2{非法,統(tǒng)計(jì)值和字段不能混合出現(xiàn)在一個(gè)表達(dá)式中}
          11.4.2 指定分組
            默認(rèn)情況下,統(tǒng)計(jì)值是基于數(shù)據(jù)集中所有的記錄計(jì)算出來(lái)的。不過(guò),也可以針對(duì)一部分記錄計(jì)算統(tǒng)計(jì)值,這就需要事先建立分組。
            前面在介紹索引時(shí)已經(jīng)提到分組的概念。可以通過(guò)IndexName屬性和GroupingLevel屬性來(lái)選擇使用哪個(gè)索引以及最大的分組級(jí)別。
            例如,假設(shè)有一個(gè)表是這樣的:
          SalesRep Customer OrderNo Amount
          1      1     5    100
          1      1     2    50
          1      2     3    200
          1       2     6    75
          2      1     1    10
          2      3     4    200
            如果要按SalesRep字段分組,并且指定其中的第一級(jí),程序代碼應(yīng)當(dāng)這樣寫(xiě):
          Agg.Expression := 'Sum(Amount)';
          Agg.IndexName := 'SalesCust';
          Agg.GroupingLevel := 1;
          Agg.AggregateName := 'Total for Rep';
          11.4.3 怎樣獲取統(tǒng)計(jì)值
            要獲取統(tǒng)計(jì)值,可以調(diào)用TAggregate對(duì)象的Value函數(shù)。如果統(tǒng)計(jì)值是基于數(shù)據(jù)集中所有的記錄計(jì)算出來(lái)的,隨時(shí)可以調(diào)用Value函數(shù)。如果統(tǒng)計(jì)值是基于分組計(jì)算出來(lái)的,必須保證當(dāng)前記錄正好位于該分組內(nèi)。因此,在調(diào)用Value之前,最好先調(diào)用GetGroupState函數(shù)看看當(dāng)前記錄是否位于該分組內(nèi)。
            要在數(shù)據(jù)控件中顯示統(tǒng)計(jì)值,必須事先在字段編輯器中創(chuàng)建一個(gè)永久字段對(duì)象,該字段的類型必須是Aggregate。
          11.5 數(shù) 據(jù) 包
            通過(guò)Data屬性可以訪問(wèn)客戶程序從應(yīng)用服務(wù)器檢索到的數(shù)據(jù)。程序示例如下:
          Procedure TForm1.Button1Click(Sender: TObject);
          Begin
          ClientDataSet1.Data := ClientDataSet1.Provider.DataRequest(FilterEdit.Text);
          End;
          11.5.1 直接對(duì)Data屬性賦值
            前面講過(guò),客戶程序既可以通過(guò)IProvider接口獲取數(shù)據(jù),也可以從另一個(gè)數(shù)據(jù)集獲取數(shù)據(jù),后者就是通過(guò)Data屬性賦值的。程序示例如下:
            ClientDataSet1.Data := ClientDataSet2.Data;
            一旦Data被賦值,就可以用標(biāo)準(zhǔn)的數(shù)據(jù)控件顯示這些數(shù)據(jù)。
            注意:當(dāng)從另一個(gè)數(shù)據(jù)集獲取數(shù)據(jù)時(shí),另一個(gè)數(shù)據(jù)集的日志也將被復(fù)制過(guò)來(lái),但不包括原來(lái)的范圍和過(guò)濾條件。
            如果要從另一個(gè)基于BDE的數(shù)據(jù)集中獲取數(shù)據(jù),可以通過(guò)數(shù)據(jù)集構(gòu)件的Provider屬性,程序示例如下:
            ClientDataSet1.Data := Table1.Provider.Data;
            如果要從一個(gè)自定義的數(shù)據(jù)集獲取數(shù)據(jù),首先要?jiǎng)?chuàng)建一個(gè)臨時(shí)的TProvider構(gòu)件,然后設(shè)置其DataSet屬性指定這個(gè)自定義的數(shù)據(jù)集。程序示例如下:
          TempProvider := TDataSetProvider.Create(Form1);
          TempProvider.DataSet := SourceDataSet;
          ClientDataSet1.Data := TempProvider.Data;
          TempProvider.Free;
          11.5.2 在數(shù)據(jù)包中加入自定義的信息
            可以把自定義的信息加到數(shù)據(jù)包中。當(dāng)把數(shù)據(jù)保存到文件或流中時(shí),這些自定義的信息也將保存到文件或流中。如果把數(shù)據(jù)包直接賦值給另一個(gè)數(shù)據(jù)集的話,這些自定義的信息也將被復(fù)制。
            要把自定義的信息加到數(shù)據(jù)包中,可以調(diào)用SetOptionalParam函數(shù)。要從數(shù)據(jù)包中檢索自定義的信息,可以調(diào)用GetOptionalParam。程序示例如下:
          Procedure TAppServer.Provider1UpdateData(Sender: TObject; DataSet: TClientDataSet);
          var
          WhenProvided: TDateTime;
          Begin
          WhenProvided := DataSet.GetOptionalParam('TimeProvided');
          ...
          End;
          11.5.3 克隆另一個(gè)數(shù)據(jù)集
            調(diào)用TClientDataSet的CloneCursor函數(shù)可以獲得一個(gè)數(shù)據(jù)集的完全相同的副本。它與直接通過(guò)Data屬性賦值是有區(qū)別的。
            區(qū)別之一:數(shù)據(jù)在兩個(gè)數(shù)據(jù)集之間是共享的,修改其中一個(gè)將同時(shí)修改另一個(gè)。
            區(qū)別之二:除了數(shù)據(jù)外,CloneCursor函數(shù)還復(fù)制了一些屬性和事件,這取決于Reset和KeepSettings參數(shù)怎樣設(shè)置。
             CloneCursor函數(shù)需要傳遞三個(gè)參數(shù),其中,Source參數(shù)指定源數(shù)據(jù)集,Reset參數(shù)和KeepSettings參數(shù)用于設(shè)置除了數(shù)據(jù)外是否還要復(fù)制下列屬性和事件:Filter、Filtered、FilterOptions、OnFilterRecord、IndexName、MasterSource、MasterFields、ReadOnly、RemoteServer、ProviderName、Provider。
            如果Reset和KeepSettings參數(shù)都設(shè)為False,源數(shù)據(jù)集的上述屬性和事件都將被復(fù)制給目標(biāo)數(shù)據(jù)集。如果Reset參數(shù)設(shè)為True,目標(biāo)數(shù)據(jù)集的上述屬性和事件都將被清空。如果Reset參數(shù)設(shè)為False,而KeepSettings參數(shù)設(shè)為True,目標(biāo)數(shù)據(jù)集的上述屬性和事件不變,不過(guò),必須保證這些屬性和事件與克隆后的數(shù)據(jù)相容。
          11.6 與應(yīng)用服務(wù)器通訊
            在多層體系結(jié)構(gòu)中,客戶程序通過(guò)IProvider接口與應(yīng)用服務(wù)器交換數(shù)據(jù)。這一章介紹怎樣在客戶端獲得IProvider接口、怎樣向應(yīng)用服務(wù)器傳遞參數(shù)、怎樣向應(yīng)用服務(wù)器請(qǐng)求數(shù)據(jù)、怎樣把用戶對(duì)數(shù)據(jù)的修改寫(xiě)到數(shù)據(jù)庫(kù)中。
          11.6.1 怎樣在客戶端獲得IProvider接口
            在單層應(yīng)用程序以及工作在“公文包”模式下的多層應(yīng)用程序中,不需要用到IProvider接口。而在多層體系結(jié)構(gòu)中,客戶程序要與應(yīng)用服務(wù)器交換數(shù)據(jù),首先必須獲得IProvider接口,這就要用到RemoteServer屬性和ProviderName屬性。
            RemoteServer屬性用于指定客戶端的MIDAS連接構(gòu)件。MIDAS連接構(gòu)件又稱Data Broker,用于建立和維護(hù)與應(yīng)用服務(wù)器的連接。
            在設(shè)計(jì)期,正確設(shè)置了RemoteServer屬性后,就可以在對(duì)象觀察器中為ProviderName屬性選擇一個(gè)值,實(shí)際上就是選擇應(yīng)用服務(wù)器上的一個(gè)TProvider構(gòu)件。
          11.6.2 向應(yīng)用服務(wù)器傳遞參數(shù)
            客戶程序可以向應(yīng)用服務(wù)器傳遞參數(shù),這些參數(shù)實(shí)際上是傳遞給應(yīng)用服務(wù)器上的TQuery構(gòu)件或TStoredProc構(gòu)件。既可以在設(shè)計(jì)期也可以在運(yùn)行期設(shè)置參數(shù)。
            在設(shè)計(jì)期,可以單擊Params屬性邊上的省略號(hào)按鈕,打開(kāi)一個(gè)如圖11.2所示的編輯器。
            圖11.2 設(shè)置參數(shù)
            單擊按鈕可以增加一個(gè)參數(shù),單擊按鈕可以刪減一個(gè)參數(shù),單擊按鈕可以把一個(gè)參數(shù)前移,單擊按鈕可以把一個(gè)參數(shù)后移。
            選擇一個(gè)參數(shù),對(duì)象觀察器將顯示該參數(shù)(TParam對(duì)象)的屬性。
            在運(yùn)行期可以調(diào)用TParams的CreateParam函數(shù)來(lái)創(chuàng)建一個(gè)參數(shù)。例如,下面的代碼創(chuàng)建了一個(gè)參數(shù)叫CustNo,它的使用類型是ptInput,數(shù)據(jù)類型是ftInteger,它的值設(shè)為605。
          With ClientDataSet1.Params.CreateParam(ftInteger, 'CustNo', ptInput) Do
          AsInteger := 605;
            設(shè)置好參數(shù)以后,如果TClientDataset的Active屬性是False,只要把Active屬性設(shè)為True,這些參數(shù)將被自動(dòng)傳遞給應(yīng)用服務(wù)器。如果Active屬性已經(jīng)為True,就要調(diào)用SendParams函數(shù)把參數(shù)傳遞給應(yīng)用服務(wù)器。
            注意:傳遞給應(yīng)用服務(wù)器的參數(shù)必須與TQuery構(gòu)件或TStoredProc構(gòu)件的參數(shù)匹配,包括名稱、數(shù)據(jù)類型和參數(shù)類型。
          11.6.3 怎樣向應(yīng)用服務(wù)器請(qǐng)求數(shù)據(jù)
            TClientDataSet提供了兩個(gè)屬性和三個(gè)方法,用于怎樣向應(yīng)用服務(wù)器請(qǐng)求數(shù)據(jù):
            一是FetchOnDemand屬性。如果這個(gè)屬性設(shè)為True,TClientDataSet會(huì)根據(jù)需要自動(dòng)檢索附加的數(shù)據(jù)包,例如BLOB字段的值或者嵌套表的內(nèi)容。如果這個(gè)屬性設(shè)為False,程序需要顯式地調(diào)用GetNextPacket才能獲得這些附加的數(shù)據(jù)包。
            二是PacketRecords屬性,用于設(shè)置一個(gè)數(shù)據(jù)包中最多可容納的記錄數(shù),設(shè)為-1表示一個(gè)數(shù)據(jù)包可以容納數(shù)據(jù)集的所有記錄。
            三是GetNextPacket函數(shù),用于向應(yīng)用服務(wù)器檢索下一個(gè)數(shù)據(jù)包,并把檢索到的數(shù)據(jù)包添加到前一次檢索到的數(shù)據(jù)包的后面。這個(gè)函數(shù)返回實(shí)際檢索到的記錄數(shù)。
            四是FetchBlobs過(guò)程,用于從應(yīng)用服務(wù)器檢索BLOB字段的值。如果FetchOnDemand屬性設(shè)為True,就沒(méi)必要調(diào)用FetchBlobs函數(shù)。
            五是FetchDetails過(guò)程,用于檢索嵌套表中的數(shù)據(jù)。如果FetchOnDemand屬性設(shè)為True,就沒(méi)必要調(diào)用FetchDetails函數(shù)。
          11.6.4 更新數(shù)據(jù)庫(kù)
            在多層體系結(jié)構(gòu)中,用戶在客戶端修改了數(shù)據(jù)后,需要把最新的數(shù)據(jù)寫(xiě)到數(shù)據(jù)庫(kù)中,這就要調(diào)用TClientDataSet的ApplyUpdates函數(shù)。
            ApplyUpdates只需要傳遞一個(gè)參數(shù)叫MaxErrors,用于指定一個(gè)整數(shù),當(dāng)遇到無(wú)法更新的記錄超過(guò)這個(gè)數(shù)時(shí),此次更新就中止。如果MaxErrors參數(shù)設(shè)為0,表示只要遇到一個(gè)錯(cuò)誤更新就中止,客戶端的日志保持不變。如果MaxErrors參數(shù)設(shè)為-1,當(dāng)應(yīng)用服務(wù)器發(fā)現(xiàn)有錯(cuò)誤的記錄,就嘗試更新下一個(gè)記錄,等所有的記錄都嘗試過(guò)以后才返回。
            ApplyUpdates會(huì)自動(dòng)調(diào)用Reconcile函數(shù),進(jìn)而調(diào)用應(yīng)用服務(wù)器上的TProvider構(gòu)件的ApplyUpdates函數(shù)去更新遠(yuǎn)程的數(shù)據(jù)庫(kù)服務(wù)器。沒(méi)有被DBMS服務(wù)器認(rèn)可的記錄通過(guò)Reconcile返回給客戶端,此時(shí)將在客戶端觸發(fā)OnReconcileError事件讓您更正錯(cuò)誤。最后,ApplyUpdates函數(shù)返回仍然沒(méi)有被認(rèn)可的記錄數(shù)。
          11.7 在文件中存取數(shù)據(jù)
            要從文件中讀取數(shù)據(jù),可以調(diào)用LoadFromFile函數(shù)。LoadFromFile函數(shù)需要傳遞一個(gè)參數(shù),用于指定文件名。文件名應(yīng)包含完整的路徑。如果客戶程序總是從一個(gè)固定的文件中讀取數(shù)據(jù),可以設(shè)置FileName屬性指定一個(gè)文件名,以后,當(dāng)TClientDataSet引入的數(shù)據(jù)集打開(kāi)時(shí),就自動(dòng)從這個(gè)文件中讀取數(shù)據(jù),不需要調(diào)用LoadFromFile。
            要從流中讀取數(shù)據(jù),可以調(diào)用LoadFromStream。LoadFromStream需要傳遞一個(gè)參數(shù),用于指定一個(gè)流對(duì)象。
            注意:LoadFromFile(LoadFromStream)只能從先前用SaveToFile(SaveToStream)保存的文件中讀取數(shù)據(jù)。
            要把數(shù)據(jù)保存到文件中,可以調(diào)用SaveToFile函數(shù)。SaveToFile需要傳遞一個(gè)參數(shù),用于指定文件名。如果指定的文件已存在,文件中的數(shù)據(jù)將被覆蓋。如果客戶程序總是把數(shù)據(jù)保存到一個(gè)固定的文件中,可以設(shè)置FileName屬性指定一個(gè)文件名,當(dāng)TClientDataSet引入的數(shù)據(jù)集關(guān)閉時(shí),就自動(dòng)把數(shù)據(jù)保存到這個(gè)文件中,不需要調(diào)用SaveToFile。
            要把數(shù)據(jù)保存到流中,可以調(diào)用SaveToStream。SaveToStream需要傳遞一個(gè)參數(shù),指定一個(gè)流對(duì)象。
            注意:當(dāng)把數(shù)據(jù)保存到文件或流中時(shí),日志中記載的修改仍然保留。這樣,當(dāng)下次調(diào)用LoadFromFile或LoadFromStream讀取數(shù)據(jù)時(shí),仍然可以恢復(fù)原來(lái)的數(shù)據(jù)。
          posted @ 2007-03-29 05:57 konhon 優(yōu)華 閱讀(1649) | 評(píng)論 (0)編輯 收藏

          2007年3月28日 #

          ? 近日(呵呵,這篇文章是去年寫(xiě)的)用了兩個(gè)月開(kāi)發(fā)了一個(gè)物流信息系統(tǒng),這個(gè)系統(tǒng)是兩層、三層相結(jié)合,C/SB/S相結(jié)合的系統(tǒng)。雖然限于時(shí)間的緊張和人手的原因,系統(tǒng)規(guī)模不是很大,但是其中涉及的技術(shù)卻很全面。在這個(gè)《開(kāi)發(fā)技術(shù)篇》中我們將講解我在開(kāi)發(fā)系統(tǒng)中遇到的技術(shù)問(wèn)題及解決方案,希望對(duì)大家有幫助。對(duì)于物流信息系統(tǒng)的分析設(shè)計(jì)問(wèn)題,我將在另一篇文章《物流信息系統(tǒng)開(kāi)發(fā)手記――系統(tǒng)構(gòu)架篇》中講解。

          ?

          一、Midas的安全問(wèn)題。

          ??? Midas技術(shù)是Delphi中進(jìn)行三層開(kāi)發(fā)的首選技術(shù),它不僅有純DCOM/COM+(COM+技術(shù)是.NET技術(shù)的基礎(chǔ))的優(yōu)點(diǎn),而且也結(jié)合了Delphi的快速開(kāi)發(fā)特性,可以快速開(kāi)發(fā)出想要的系統(tǒng),其開(kāi)發(fā)速度是用VC,PB等開(kāi)發(fā)DCOM的數(shù)十倍,把程序員從煩雜的代碼中解脫出來(lái),從而將更多的精力投入到業(yè)務(wù)邏輯的設(shè)計(jì)中去。

          ??? 但是Midas技術(shù)的一個(gè)最令人擔(dān)憂的就是它的安全問(wèn)題:

          遠(yuǎn)端只要知道應(yīng)用服務(wù)器的端口號(hào)即可訪問(wèn)到應(yīng)用服務(wù)器,而一旦訪問(wèn)到應(yīng)用服務(wù)器,TClientDataSet即可獲得ProviderNames列表。一旦知道了ProviderNames列表,這就相當(dāng)于將數(shù)據(jù)庫(kù)暴露在外了。

          關(guān)于可輕易獲得ProviderNames列表的問(wèn)題,我使用下面的方法解決:

          ?在服務(wù)器端定義一個(gè)

          LoginMTS(const AUserId, APassword: WideString): WordBool;

          方法。初始狀態(tài)下,所有的DataSetProvider和數(shù)據(jù)集的連接斷開(kāi)。用戶必須調(diào)用LoginMTS并傳遞用戶名和密碼,登陸成功才將DataSetProvider和數(shù)據(jù)集的連接打開(kāi)。這樣如果用戶驗(yàn)證沒(méi)有通過(guò),即使它獲得了ProviderNames列表也沒(méi)法調(diào)用接口中的方法對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作。

          二、Midas中主從表的實(shí)現(xiàn)

          主從表的應(yīng)用在信息系統(tǒng)中應(yīng)用很廣。在兩層開(kāi)發(fā)中我們可以通過(guò)直接建立兩個(gè)數(shù)據(jù)集之間為主從關(guān)系來(lái)實(shí)現(xiàn)主從表;在三層中雖然我們?nèi)匀豢梢酝ㄟ^(guò)直接建立兩個(gè)數(shù)據(jù)集之間為主從關(guān)系來(lái)實(shí)現(xiàn)主從表,但是這樣就要求把數(shù)據(jù)庫(kù)中所有相關(guān)的數(shù)據(jù)行都下載到本地,喪失了三層開(kāi)發(fā)的優(yōu)勢(shì)。我在實(shí)際中使用下面的方法實(shí)現(xiàn)。這里我以實(shí)現(xiàn)入庫(kù)單查詢、添加、修改、刪除(CRUD)為例來(lái)講解:

          1)新建一個(gè)MTS Data Module,命名為TmtsStockInListBiz,增加如下方法:

          ??? function QueryStockInListMasterById(const AId: WideString;

          ????? var ADatas: OleVariant): WordBool; safecall;

          ??? function QueryStockInListSlaveByMasterId(const AId: WideString;

          ????? var ADatas: OleVariant): WordBool; safecall;

          ??? procedure UpdataStockInListMaster(var ADatas: OleVariant); safecall;

          ??? procedure UpdataStockInListSlave(var ADatas: OleVariant); safecall;

          ??? function GenerateStockInListId: WideString; safecall;

          ?

          QueryStockInListMasterById作用是根據(jù)入庫(kù)單單號(hào)查詢?nèi)霂?kù)單的基本信息(入庫(kù)日期、負(fù)責(zé)人等),Aid為入庫(kù)單單號(hào),Adatas為返回值,其格式就是Midas的數(shù)據(jù)包,可以將其附給ClientDatSetData屬性。

          QueryStockInListSlaveByMasterId作用是根據(jù)入庫(kù)單單號(hào)查詢?nèi)霂?kù)單的詳細(xì)信息(商品條碼,數(shù)量)

          UpdataStockInListMaster是對(duì)入庫(kù)單主表進(jìn)行刪除、添加、修改操作。只要將ClientDataSetDelta屬性做為傳遞即可。

          UpdataStockInListSlave是對(duì)入庫(kù)單從表進(jìn)行刪除、添加、修改操作。

          GenerateStockInListId是產(chǎn)生一個(gè)唯一的入庫(kù)單號(hào)。

          下面是幾個(gè)方法的代碼,都很簡(jiǎn)單,就不多解釋了,可以查看Delphi的幫助。

          function TmtsStockInListBiz.QueryStockInListMasterById(

          ? const AId: WideString; var ADatas: OleVariant): WordBool;

          begin

          ? result := false;

          ? ADatas := null;

          ? try

          ??? cdsQuery.Close;

          ??? cdsQuery.CommandText := 'select * from t_StockInListMaster where Id=:Id';

          ??? cdsQuery.Params.ParamByName('Id').AsString := AId;

          ??? cdsQuery.Open;

          ??? if cdsQuery.RecordCount > 0 then

          ??? begin

          ????? result := true;

          ????? ADatas := cdsQuery.Data;

          ??? end;

          ? finally

          ??? cdsQuery.Close;

          ? end;

          end;

          ?

          procedure TmtsStockInListBiz.UpdataStockInListMaster(

          ? var ADatas: OleVariant);

          var

          ? eCount: Integer;

          ? OwnerData: OleVariant;

          begin

          ? DCOMConStockInList.GetServer.AS_ApplyUpdates('dspStockInListMaster',

          ??? ADatas, -1, eCount, OwnerData);

          end;

          ?

          function TmtsStockInListBiz.GenerateStockInListId: WideString;

          var

          ? LPrior: string;

          ? i: Integer;

          begin

          ? cdsQuery.Close;

          ? cdsQuery.CommandText := 'select top 1 id from t_StockInListMaster order by id desc';

          ? cdsQuery.Open;

          ? LPrior := cdsQuery.FieldByName('Id').AsString;

          ? i := StrToIntDef(RightStr(LPrior,8),0);

          ? Inc(i);

          ? result := 'RK' + FormatFloat('00000000',i);

          ? cdsQuery.Close;

          end;

          ?

          2)、新建一個(gè)應(yīng)用程序,通過(guò)DCOMConnectionSocketConnection等連接到MTS組件,然后就可以調(diào)用MTS的相應(yīng)的方法實(shí)現(xiàn)客戶端功能了。

          放入cdsStockInListMastercdsStockInListSlave兩個(gè)ClientDataSet控件,在控件上點(diǎn)擊右鍵,選擇“FieldsEditor”新建于服務(wù)器中的字段同樣的字段,然后再次在控件上單擊右鍵,選擇“CreateDataSet”,建立一個(gè)本地?cái)?shù)據(jù)庫(kù)。

          3

          根據(jù)入庫(kù)單號(hào)查詢?nèi)霂?kù)單的方法實(shí)現(xiàn):

          procedure TFormStockInList.BtnFindClick(Sender: TObject);

          var

          ? v,vs: OleVariant;

          begin

          ? if SocketConStockInList.AppServer.QueryStockInListMasterById(Trim(LEdtId.Text), v) then

          ? begin

          ??? cdsStockInListMaster.Data := v;//顯示入庫(kù)單主表(主要信息)

          ?

          ??? if SocketConStockInList.AppServer.QueryStockInListSlaveByMasterId(Trim(LEdtId.Text), vs) then

          ????? cdsStockInListSlave.Data := vs; ;//顯示入庫(kù)單從表(明細(xì)信息)

          ? end

          ? else

          ??? ShowMessage('此單不存在!');

          end;

          4)新建入庫(kù)單的實(shí)現(xiàn)

          procedure TFormStockInList.BtnNewClick(Sender: TObject);

          var

          ? LId: string;

          begin

          ? ClearCDSRecord;

          ? cdsStockInListMaster.Open;

          ? cdsStockInListMaster.Insert;

          ? LId := SocketConStockInList.AppServer.GenerateStockInListId;

          ? LEdtId.Text := LId;

          ? cdsStockInListMaster.FieldByName('Id').AsString := LId;

          ? cdsStockInListMaster.FieldByName('GenerateDate').AsDateTime := Now();

          end;

          5)提交功能的實(shí)現(xiàn)

          procedure TFormStockInList.BtnPostClick(Sender: TObject);

          var

          ? LQuerymts: ImtsQueryObjDisp;

          ? LBar: string;

          begin

          ? SetSocketConnectionConnect(SocketConQuery);

          ? LQuerymts := ImtsQueryObjDisp(SocketConQuery.GetServer);

          ?

          ? SocketConQuery.Close;

          ?

          ? if cdsStockInListMaster.RecordCount > 0 then

          ??? SocketConStockInList.AppServer.UpdataStockInListMaster(cdsStockInListMaster.Delta);

          ? if cdsStockInListSlave.RecordCount > 0 then

          ? SocketConStockInList.AppServer.UpdataStockInListSlave(cdsStockInListSlave.Delta);

          end;

          注:本文中ClientDataSet控件的名稱開(kāi)頭一般為cdsTsocketConnection控件的名稱開(kāi)頭一般為SocketCon

          三、動(dòng)態(tài)設(shè)置TsimpleObjectBroker的服務(wù)器列表

          procedure SetSocketConnectionConnect(AValue: TSocketConnection);

          ? procedure FillAppServerList(ABroker: TSimpleObjectBroker);

          ? var

          ??? sl: TStringList;

          ??? i, n: Integer;

          ? begin

          ??? sl := TStringList.Create;

          ??? 從配置文件中讀取服務(wù)器列表,并保存到sl;

          ??? n := sl.Count - 1;

          ??? ABroker.ServerData := null;

          ??? for i := 0 to n do

          ??? begin

          ????? ABroker.Servers.Add;

          ????? ABroker.Servers[i].ComputerName := sl.Strings[i]

          ?? ?end;

          ??? sl.Free;

          ? end;

          var

          ? LBroker: TSimpleObjectBroker;

          begin

          ? LBroker := TSimpleObjectBroker.Create(nil);

          ??? FillAppServerList(LBroker);

          ??? AValue.ObjectBroker := LBroker;

          ??? try

          ????? AValue.Connected := true;

          ??? except

          ????? raise Exception.Create('應(yīng)用服務(wù)器連接錯(cuò)誤!');

          ??? end;

          ??? LBroker.Free;

          end;

          posted @ 2007-03-28 05:07 konhon 優(yōu)華 閱讀(2580) | 評(píng)論 (0)編輯 收藏


            因?yàn)樾枰幚泶罅康囊簟⒁曨l數(shù)據(jù),所以一套強(qiáng)有力的計(jì)算機(jī)系統(tǒng)及外圍硬件配置是必要的。另外,由于我們要直接輸出的是高質(zhì)量的MPG文件(而非體積龐大的AVI文件),因此,強(qiáng)烈建議使用視頻壓縮卡進(jìn)行硬件高速壓縮,本文以較常見(jiàn)的MPEGator 3.1壓縮卡為例,介紹通過(guò)Premiere利用壓縮卡直接輸出MPG的辦法:

            1、制作VCD電子相冊(cè)應(yīng)使用怎樣的系統(tǒng)配置?

            答:推薦的系統(tǒng)配置如下---

            CPU: PIII 500E以上

            內(nèi)存: 256M SDRAM或更大

            硬盤(pán): 20G高速

            壓縮卡:MPEGator 3.1 刻錄機(jī):所有能被Video Pack 4.0所支持的型號(hào)

            操作系統(tǒng):Windows 95 OSR2或Windows 98 制作軟件:Adobe Premiere 5.0/4.2、Video Pack 4.0

            輔助軟件:Paint shop Pro 6.0、ACDsee3.0、Audio Grabber 1.61 以上推薦的系統(tǒng)配置中,我們主要是采用了著名的視頻編輯軟件Adobe Premiere 5.0與性能價(jià)格比較高的MPEGator 3.0壓縮卡配合制作VCD相冊(cè)。為什么要采用這樣的配合呢?還是先讓我們來(lái)了解一下它們各自的特性吧:

            2、為什么推薦使用Premiere 5.0數(shù)字影視編輯軟件?

            答:Adobe Premiere 5.0是圖形圖像軟件巨人---Adobe公司繼廣受稱贊的Premiere 4.2后,推出的新一代桌面數(shù)字影視編輯系統(tǒng)。它具有比Premiere 4.2更為強(qiáng)大的圖像編輯能力,通過(guò)把動(dòng)畫(huà)、位圖、數(shù)字音頻文件按照需要進(jìn)行剪輯、組合,讓你可以設(shè)計(jì)出近乎隨心所欲的影視特效;在專為編輯影像片段而設(shè)計(jì)的Timeline里,利用鼠標(biāo)就可完成所有的編輯操作;它的即時(shí)播放功能還使我們?cè)诎l(fā)生編輯錯(cuò)誤時(shí),能夠輕松地進(jìn)行修改,以節(jié)省時(shí)間與精力。更重要的是,Premiere 5.0可以提供高品質(zhì)影像輸出質(zhì)量!這一點(diǎn)著實(shí)令人心動(dòng)。此外,它還支持制作輸出有聲有色的VCD電子相冊(cè)呢。

            3、為什么推薦使用MPEGator壓縮卡?

            答:壓縮卡方面,韓國(guó)DARIM公司生產(chǎn)的MPEGator壓縮卡(圖02)可謂是具有較高性能價(jià)格比的視頻壓縮卡:不僅帶有S-video、復(fù)合、及立體聲音頻輸入接口,可以通過(guò)攝像機(jī)、錄像機(jī)、電視及激光唱機(jī)等信號(hào)源將視頻信號(hào)實(shí)時(shí)壓縮成全I(xiàn).P.B幀的標(biāo)準(zhǔn)MPEG-1格式;還支持實(shí)時(shí)預(yù)覽。最為重要的是MPEGator卡可以使流行的視頻編輯軟件通過(guò)硬件加速轉(zhuǎn)換成為MPEG-1格式。  MPEGator可與Windows的其它應(yīng)用程序配合產(chǎn) PEG文件,3D Studio, Adobe Premiere等各種兼容Video for Window的流行的編輯軟件都可以在生成動(dòng)畫(huà)或AVI之前,直接選用其壓縮驅(qū)動(dòng)程序,通過(guò)硬件加速壓縮生成為MPEG文件,有效地避免了因AVI—→MPG而導(dǎo)致的畫(huà)質(zhì)下降這一難題。另外,MPEGator還具有PAL/NTSC制式兼容,PCI32位總線等特點(diǎn)。通過(guò)以上介紹,可以看出:利用這樣的軟硬件組合,我們將能夠制作出效果比較令人滿意的多媒體VCD相冊(cè)。下面,就讓我們開(kāi)始實(shí)戰(zhàn)VCD相冊(cè)的制作吧。

            4.制作VCD相冊(cè)之前,為什么要擬定提綱?

            答:制作VCD相冊(cè)之前,首先應(yīng)對(duì)所制作的作品的各個(gè)方面做到心中有數(shù)。最好列個(gè)制作提綱,列出主題及各相對(duì)獨(dú)立片段的次序,以及每個(gè)片段內(nèi)的照片、音樂(lè)、旁白;將每張照片分別編上序號(hào),并將其序號(hào)與欲添加的說(shuō)明文字對(duì)應(yīng)起來(lái)。這樣,在實(shí)際制作的時(shí)候就條理清晰、步驟分明,不易出現(xiàn)錯(cuò)漏等現(xiàn)象。

            5.怎樣進(jìn)行照片的掃描?

            答:選取一張淺色紋理紙,將其裁剪成寬155mm、高127mm(即352:288)大小的矩形模板。用雙面膠將照片粘于其上(注意居中,并使底邊高度略大于頂邊),放入掃描儀進(jìn)行掃描,并以位圖(.bmp)形式存盤(pán)。此舉好處之一是使掃出的照片具有一個(gè)漂亮的彩色相框;另一個(gè)好處是可以將添加的說(shuō)明文字放在相框上,而不是照片內(nèi),不會(huì)破壞照片的美感(圖07)。?


            6. 如何為照片添加說(shuō)明文字?

            進(jìn)入Paint Shop Pro 5.0,選擇File——open打開(kāi)一幅已掃好的照片,點(diǎn)擊左側(cè)工具欄中的“A”鍵,接著將鼠標(biāo)移至照片內(nèi)并單擊左鍵,在彈出的“Add Text”文字輸入框中輸入想要的文字,再選定字體、字號(hào)及顏色,確定文字位置后點(diǎn)擊“OK”,并將編輯后的照片以原文件名存盤(pán)。

           7.如何截取音軌?

            答:?jiǎn)?dòng)音軌截取軟件AudioGrabber,將音樂(lè)CD放入光驅(qū),勾選想要截取的CD音軌。

            點(diǎn)擊控制欄中的“Settings”按鍵后勾選其中的“ASPI”項(xiàng),其它選項(xiàng)用默認(rèn)值即可。然后,進(jìn)入“Norm”選項(xiàng),選擇“Use normalizing”后點(diǎn)擊“OK”退出。現(xiàn)在,先用鼠標(biāo)點(diǎn)擊一下工具欄里那標(biāo)有伸開(kāi)手掌的“截取”(Grab)鈕,就可以開(kāi)始抓取指定的音軌了。如果截獲的.WAV文件不能被正常讀取或者.WAV文件中有令人討厭的“爆音”(pops,這是令許多朋友頭痛的問(wèn)題)。請(qǐng)?jiān)凇伴_(kāi)始—設(shè)置—控制面板—系統(tǒng)—設(shè)備管理—CDROM—屬性—設(shè)置—選項(xiàng)”中將“同步數(shù)據(jù)傳送”選中,然后按“確定”退出。再重新去試截取剛才有問(wèn)題的音軌,您可能會(huì)發(fā)現(xiàn),問(wèn)題已經(jīng)迎刃而解了。其次,若覺(jué)得光驅(qū)讀取音樂(lè)數(shù)據(jù)的速度很緩慢,請(qǐng)先檢查光驅(qū)上數(shù)據(jù)線是否直接接到了主板的IDE接口上。

            為了方便管理和使用,可新建Photo、Audio、Wav三個(gè)子目錄,分別用于存放照片、音樂(lè)及旁白。

            準(zhǔn)備工作完成后,就可以開(kāi)始著手制作了。為了工作得更有條理,我們一般先對(duì)每一個(gè)相對(duì)獨(dú)立的片段進(jìn)行編輯制作,最后再把它們連成整體。

            8.如何設(shè)置才能讓Premier5.0利用MPEGator來(lái)進(jìn)行高效硬件壓縮?

            答:首先啟動(dòng)Premiere5.0。在彈出的New Project setting窗口,選擇General settings,在“編輯模式”里選“Video for window”,其下的兩個(gè)選項(xiàng)均選“25”(因?yàn)槲覀円谱鞯氖荘AL制式的VCD);然后進(jìn)Video settings,在“壓縮器(Compressor)”這一項(xiàng)中選“DVMPEG Video (hardware)”(圖08),即選用硬件壓縮;分辨率設(shè)為352*288,幀率設(shè)為25;在Audio settings里,關(guān)鍵是在“Type(類型)”中選擇“DVMPEG Audio”---指定用硬件進(jìn)行音頻壓縮;采樣頻率設(shè)為44.1KHZ,格式設(shè)為16bit--Stereo。


            9.Premiere 5.0的主界面的結(jié)構(gòu)如何?

            答:進(jìn)入Premiere 5.0的主界面,我們會(huì)發(fā)現(xiàn)設(shè)計(jì)新穎的時(shí)間軸窗口(Timeline)已取代了其4.2版本中的Constraction窗口。作為Premiere 5.0的核心,Timeline的用戶窗口分為兩個(gè)部份:視頻部分和音頻部分;其中視頻部份又分為兩個(gè)主視頻剪輯軌道——Video 2和Video 1。其中,標(biāo)成黑體字的Video 1部份又內(nèi)含兩個(gè)視頻剪輯軌道:Video 1A和Video 1B,它們之間的Transition軌道是視頻切換效果軌道。Premiere 5.0提供了非常豐富的視頻切換效果,包括滑動(dòng)、擦除、融合、剝落、分割、爆破、漸變、突變、三維旋轉(zhuǎn)、翻頁(yè)、推動(dòng)等多種劃變效果,令人目不暇接。音頻軌道Audio 1、2、3則用于放置背景音樂(lè)、配音、旁白等聲音信號(hào)。  

            10.如何導(dǎo)入圖片及配音文件?

            答:點(diǎn)擊“File--Import--Folder”,把剛才準(zhǔn)備好的圖片文件及背景音樂(lè)文件輸入進(jìn)來(lái),在Project窗口下雙擊剛才輸入的文件夾,可以看到文件夾中的各文件的具體信息,雙擊該文件則可對(duì)其進(jìn)行預(yù)覽。  

            11.如何設(shè)置照片的參數(shù)?

            答:將第一幅照片拖到視頻剪輯軌道Video 1A中,對(duì)其點(diǎn)擊鼠標(biāo)右鍵,在彈出的菜單中的Duration項(xiàng)里設(shè)定照片的播放時(shí)間;并在菜單中的Video項(xiàng)里將Maintain Aspect Retio選中(圖09)——請(qǐng)注意,這是非常重要的一步,此項(xiàng)設(shè)置將使最后輸出的照片保持原本的長(zhǎng)寬比例,而不致于使照片上的人像、景物發(fā)生變形。按上述方法將照片依次拖入Video1的A、B欄,(注意每幅照片的尾與下一幅照片首應(yīng)留有重疊部份,重疊部份的時(shí)間長(zhǎng)短依實(shí)際需要而定。把背景音樂(lè)、旁白拖入Audio欄)。如果是旁白,應(yīng)特別注意旁白的時(shí)間長(zhǎng)度應(yīng)與相應(yīng)照片的播放時(shí)間相當(dāng)。然后,用鼠標(biāo)把Timeline窗戶上方的淺藍(lán)色橫杠拉至最后一張照片的末端,以設(shè)定Premiere將進(jìn)行處理的視頻片段的長(zhǎng)度。


            12. 如何設(shè)定視頻切換特效?

            答:Premiere 5.0用戶界面上,有一個(gè)Transition/Command命令窗口,其中共有75種切換特效可供選擇。而且,其中大多數(shù)切換特效都可按自己的需要進(jìn)行設(shè)置。將選中的特效用鼠標(biāo)拖到Video 1窗口的Transition中兩幅照片相重疊的部分,其長(zhǎng)度應(yīng)為兩幅照片相重疊的長(zhǎng)度。如果能根據(jù)每幅照片的特點(diǎn)恰當(dāng)?shù)剡x擇Transitions,將使您的VCD相冊(cè)在播放時(shí)贏得更多的贊嘆之聲。  

            13. 如何處理背景音樂(lè)?

            答:為VCD相冊(cè)添加優(yōu)美的背景音樂(lè),也將使你的VCD相冊(cè)平添許多迷人的魅力。然而,因?yàn)楸尘耙魳?lè)是我們采用抓音軌的方式獲得的,這樣就不可避免地在VCD相冊(cè)一開(kāi)始播放時(shí)就出現(xiàn)突兀而至的音樂(lè)聲。此外,由于音軌的長(zhǎng)度與照片播放時(shí)間的長(zhǎng)度往往難以很好的吻合。這樣,就可能出現(xiàn)一段VCD相冊(cè)的播放馬上就要結(jié)束,而音樂(lè)聲卻正處于高潮……。理想的狀況應(yīng)該是:照片播放時(shí),背景音樂(lè)逐漸輕柔地響起;照片播放即將結(jié)束時(shí),音樂(lè)聲又漸漸隨之淡去。換句話說(shuō),也就是要實(shí)現(xiàn)背景音樂(lè)的淡入淡出。在Premiere 5.0中,按前述方法裝入照片及背景音樂(lè)后,單擊第一音頻軌道(Audio 1)上的那個(gè)指向右的小三角,這時(shí)會(huì)彈出該音軌的波形顯示框。可以看到該框中部有一條左右各有一方形端點(diǎn)的紅線——這就是控制音樂(lè)淡入淡出的關(guān)鍵。將鼠標(biāo)移至紅線上,鼠標(biāo)指針將變?yōu)槭中?圖10)。此時(shí),按住鼠標(biāo)左鍵即可通過(guò)增加和拖動(dòng)點(diǎn)子來(lái)隨意確定該紅線條形狀。從起始位置開(kāi)始,將線條置于從左至右漸高狀態(tài)時(shí),即可實(shí)現(xiàn)背景音樂(lè)的淡入效果。用類似的方法還可制造音樂(lè)的淡出效果,在此不再贅述。有興趣的朋友盡可自行嘗試。?

            14. 如何設(shè)置輸出參數(shù)?

            答:輸出參數(shù)包含General、Audio、Video三項(xiàng),只有正確的設(shè)備了輸出參數(shù),VCD相冊(cè)才能在VCD機(jī)上順利播放。首先選Project--Setting進(jìn)入General設(shè)置:在“Editing Mode”里選“Video for window”,“Time display”及“Timebase”均選“25”;再進(jìn)入Video設(shè)置,“Compressor”選“DVMPEG Video(Hardware)”,尺寸設(shè)為352*288,幀率設(shè)為25;最后設(shè)置Audio參數(shù):采樣頻率設(shè)為44.1KHZ,格式設(shè)為16bit--Stereo(圖11);Type設(shè)成“DVMPEG Audio”。在這里,音頻及視頻均設(shè)置為硬件(MPEGator卡)加速壓縮。?


            15. 如何直接輸出MPG文件?

            答:上述參數(shù)設(shè)置完畢后,接著選File-Export-movie,將剛才組合好的照片,音樂(lè),旁白等素材,通過(guò)MPEGator卡的硬件加速直接生成高質(zhì)量的MPG文件。我們知道,如果利用Xing MPEG Encoder等進(jìn)行純軟件壓縮,即使你的系統(tǒng)配置較高,其壓縮時(shí)間也將漫長(zhǎng)得驚人:約為真實(shí)播放時(shí)間的10-20倍;而利用MPEGator卡進(jìn)行硬件壓縮的話,可就太節(jié)省時(shí)間了:壓縮時(shí)間僅為真實(shí)播放時(shí)間的3倍左右,大大提高了制作效率。需要注意的是,為了便于分類,應(yīng)把同一主題的內(nèi)容輸出生成一個(gè)獨(dú)立的MPG文件。

            16. 如何把電子相冊(cè)刻成VCD碟?

            前面所有辛苦的勞動(dòng),都將通過(guò)刻制成VCD碟片而變成勞動(dòng)的果實(shí)。說(shuō)到2.0 VCD刻錄,CeQuadrat出品的Video Pack 4.0因其較細(xì)致而周到的功能設(shè)計(jì),是一個(gè)在業(yè)余條件下不錯(cuò)的選擇,其缺點(diǎn)是操作相對(duì)比較繁瑣。啟動(dòng)Video Pack 4.0,將剛才壓縮好的各個(gè)MPG文件依次用鼠標(biāo)拖至位于主界面下方的工作框內(nèi),右鍵單擊MPG文件,在彈出的菜單選中Properties,在Playlist node中的第二個(gè)選項(xiàng)(即每一片段的等待時(shí)間)里把等待時(shí)間設(shè)為0秒,按“確定”退出。每個(gè)MPG文件都必須重復(fù)上述步驟,這樣可以使各獨(dú)立主題內(nèi)容切換時(shí)不至于出現(xiàn)停頓等待狀態(tài)。這時(shí)你也許發(fā)現(xiàn)了,剛才拖入工作框的各MPG文件方形圖標(biāo)上下均有一個(gè)三角形缺口。原來(lái),在Video Pack 4.0中是用連線的方式來(lái)表示各種播放次序的,而這種三角形缺口,就是這些連線的出入口。將鼠標(biāo)指針移至MPG文件圖標(biāo)下方的缺口,圖標(biāo)里會(huì)出現(xiàn)黃顏色的“Next”字樣,此時(shí)即可開(kāi)始進(jìn)行連線,方法是使各MPG文件按順序首尾相連(圖12)。上述步驟完成后,點(diǎn)擊工具欄中的紅色的“Make CD”鈕即可開(kāi)始刻錄VCD光碟了。

            17. 把電子相冊(cè)刻成VCD碟的過(guò)程中要注意哪些事項(xiàng)?

            要是現(xiàn)在問(wèn)你:自己刻制一張VCD相冊(cè)光盤(pán)困難嗎?你肯定會(huì)說(shuō):一點(diǎn)都不難!

            那么,是不是就像在硬盤(pán)上拷貝文件那么輕而易舉呢?決非如此簡(jiǎn)單。VCD相冊(cè)刻錄前進(jìn)行些必要的準(zhǔn)備工作,將能大大提高我們的刻錄成功率:  

            a.刻錄前為什么要整理硬盤(pán)?

            答:我們通常都是以硬盤(pán)作為信息源盤(pán)來(lái)進(jìn)行刻錄的。由于未經(jīng)整理的磁盤(pán)文件大多呈零散狀態(tài)分布。這樣,硬盤(pán)在讀取數(shù)據(jù)時(shí),讀寫(xiě)頭就只能在零散的文件之間來(lái)回奔忙,極有可能造成不必要的延誤而導(dǎo)致刻出廢盤(pán)。所以,每次刻錄前對(duì)硬盤(pán)的每一個(gè)邏輯分區(qū)進(jìn)行磁盤(pán)掃描和碎片整理。進(jìn)行硬盤(pán)整理是成功刻錄的第一步。  

            b.為什么刻錄過(guò)程中要避免執(zhí)行任何無(wú)關(guān)程序?

            答:這些程序不僅包括屏幕保護(hù)程序和內(nèi)存駐留程序(比如某些殺毒程序),這些程序都有可能在數(shù)據(jù)流從硬盤(pán)轉(zhuǎn)移到刻錄機(jī)中光盤(pán)上的緊要關(guān)頭,來(lái)與刻錄軟件爭(zhēng)奪有限的系統(tǒng)資源,從而影響數(shù)據(jù)流的正常傳輸而引發(fā)緩存器欠載等問(wèn)題,導(dǎo)致刻盤(pán)失敗。

            c.為什么使用質(zhì)量可靠的CD-R盤(pán)片?

            答:CD-R空白盤(pán)片按反射層材料的不同可分綠盤(pán)、金盤(pán)、藍(lán)盤(pán)三大類。這三種盤(pán)片并沒(méi)有明顯的優(yōu)劣差別。從特性上來(lái)說(shuō),綠盤(pán)具有較好的兼容性,另外價(jià)格很便宜;藍(lán)盤(pán)在寫(xiě)入和讀取數(shù)據(jù)時(shí)有較高的準(zhǔn)確性;金盤(pán)有較好的抗光性。關(guān)鍵的是,分別試刻不同類別和品牌的盤(pán)片,從中找出最適合你的刻錄機(jī)的那幾種。  

            至此,兩種不同類型的電子相冊(cè)的制作方法就介紹完畢,預(yù)祝你早日制作出自己的精美電子相冊(cè)!

          posted @ 2007-03-27 19:11 konhon 優(yōu)華 閱讀(1599) | 評(píng)論 (0)編輯 收藏

          2007年3月8日 #

          首先,我們新建一個(gè)類,存放天氣信息

          /*
          ?*?Created?on?2005-3-8
          ?*
          ?*?To?change?the?template?for?this?generated?file?go?to
          ?*?Window&gt;Preferences&gt;Java&gt;Code?Generation&gt;Code?and?Comments
          ?
          */
          package ?org.exoplatform.portlets.chinaweather.component;

          /**
          ?*?
          @author ?Administrator
          ?*
          ?*?To?change?the?template?for?this?generated?type?comment?go?to
          ?*?Window&gt;Preferences&gt;Java&gt;Code?Generation&gt;Code?and?Comments
          ?
          */
          public ? class ?Weather?{
          ?
          private ?String?city;
          ?
          private ?String?state;
          ?
          private ?String?temperature;
          ?
          private ?String?time;
          ?
          private ?String?wind;
          ?
          private ?String?windpower;
          ?
          private ? long ?UpdateTime;

          ?
          /**
          ??*?
          @return
          ??
          */
          ?
          public ?String?getTemperature()?{
          ??
          return ?temperature;
          ?}

          ?
          /**
          ??*?
          @return
          ??
          */
          ?
          public ?String?getTime()?{
          ??
          return ?time;
          ?}

          ?
          /**
          ??*?
          @return
          ??
          */
          ?
          public ?String?getWind()?{
          ??
          return ?wind;
          ?}

          ?
          /**
          ??*?
          @return
          ??
          */
          ?
          public ?String?getWindpower()?{
          ??
          return ?windpower;
          ?}

          ?
          /**
          ??*?
          @param ?string
          ??
          */
          ?
          public ? void ?setTemperature(String?string)?{
          ??temperature?
          = ?string;
          ?}

          ?
          /**
          ??*?
          @param ?string
          ??
          */
          ?
          public ? void ?setTime(String?string)?{
          ??time?
          = ?string;
          ?}

          ?
          /**
          ??*?
          @param ?string
          ??
          */
          ?
          public ? void ?setWind(String?string)?{
          ??wind?
          = ?string;
          ?}

          ?
          /**
          ??*?
          @param ?string
          ??
          */
          ?
          public ? void ?setWindpower(String?string)?{
          ??windpower?
          = ?string;
          ?}

          ?
          /**
          ??*?
          @return
          ??
          */
          ?
          public ? long ?getUpdateTime()?{
          ??
          return ?UpdateTime;
          ?}

          ?
          /**
          ??*?
          @param ?l
          ??
          */
          ?
          public ? void ?setUpdateTime( long ?l)?{
          ??UpdateTime?
          = ?l;
          ?}

          ?
          /**
          ??*?
          @return
          ??
          */
          ?
          public ?String?getState()?{
          ??
          return ?state;
          ?}

          ?
          /**
          ??*?
          @param ?string
          ??
          */
          ?
          public ? void ?setState(String?string)?{
          ??state?
          = ?string;
          ?}

          ?
          /**
          ??*?
          @return
          ??
          */
          ?
          public ?String?getCity()?{
          ??
          return ?city;
          ?}

          ?
          /**
          ??*?
          @param ?string
          ??
          */
          ?
          public ? void ?setCity(String?string)?{
          ??city?
          = ?string;
          ?}

          }


          具體的解析代碼為:

          private ?Weather?parserWeather()? throws ?Exception?{
          ??Weather?w?
          = ? new ?Weather();
          ??
          try ?{

          ???
          // Parser?parser?=
          ???
          // ?new?Parser("file: // localhost/I:/projects/query.html");
          ???Parser?parser? =
          ????
          new ?Parser( " http://weather.news.sohu.com/query.php?city=鎮(zhèn)江 " );
          ???
          ???parser.setEncoding(
          " GBK " );
          ???Node?nodes[]?
          = ?parser.extractAllNodesThatAre(TableTag. class );

          ???TableTag?table?
          = ?(TableTag)?nodes[ 3 ];
          ???
          // temperature
          ???StringNode[]?stringNodes? = ?table.digupStringNode( " 鎮(zhèn)江 " );
          ???StringNode?name?
          = ?stringNodes[ 0 ];
          ???w.setCity(name.toPlainTextString());
          ???CompositeTag?td?
          = ?(CompositeTag)?name.getParent();
          ???CompositeTag?tr?
          = ?(CompositeTag)?td.getParent();
          ???
          int ?columnNo? = ?tr.findPositionOf(td);
          ???TableColumn?nextColumn?
          = ?(TableColumn)?tr.childAt( 5 );
          ???Node?expectedName?
          = ?nextColumn.childAt( 0 );
          ???Node?expectedName2?
          = ?nextColumn.childAt( 2 );
          ???
          // System.out.println(expectedName.getText());
          ???
          // System.out.println(expectedName2.getText());
          ???w.setState(expectedName.getText());
          ???w.setTemperature(expectedName2.getText());
          ???
          // time
          ???stringNodes? = ?table.digupStringNode( " 時(shí)間 " );
          ???name?
          = ?stringNodes[ 0 ];
          ???
          // System.out.println(name.toPlainTextString());

          ???String?time?
          =
          ????name
          ?????.toPlainTextString()
          ?????.substring(
          4 ,?name.toPlainTextString().length())
          ?????.trim();
          ???
          // System.out.println(time);
          ???w.setTime(time);
          ???
          // wind
          ???stringNodes? = ?table.digupStringNode( " 風(fēng)向 " );
          ???name?
          = ?stringNodes[ 0 ];
          ???
          // System.out.println(name.toPlainTextString());

          ???String?wind?
          =
          ????name
          ?????.toPlainTextString()
          ?????.substring(
          4 ,?name.toPlainTextString().length())
          ?????.trim();
          ???
          // System.out.println(wind);
          ???w.setWind(wind);
          ???
          // wind?power
          ???stringNodes? = ?table.digupStringNode( " 風(fēng)力 " );
          ???name?
          = ?stringNodes[ 0 ];
          ???
          // System.out.println(name.toPlainTextString());

          ???String?windpower?
          =
          ????name
          ?????.toPlainTextString()
          ?????.substring(
          4 ,?name.toPlainTextString().length())
          ?????.trim();
          ???
          // System.out.println(windpower);
          ???w.setWindpower(windpower);

          ???w.setUpdateTime(System.currentTimeMillis());

          ??}?
          catch ?(ParserException?e)?{

          ???e.printStackTrace();
          ??}
          ??
          return ?w;
          ?}


          解析出來(lái)的代碼必須做緩存處理,

          private ? static ? long ?TIME_TO_LIVE? = ? 1000 ? * ? 60 ? * ? 60 ? * ? 12 ;

          ?
          private ?Weather?loadWeather()? throws ?Exception?{
          ??Weather?weather?
          = ?weather? = ?(Weather)?cache_.get( " chinaweather " );
          ??
          long ?currentTime? = ?System.currentTimeMillis();
          ??
          if ?(weather? != ? null
          ???
          && ?currentTime? < ?(weather.getUpdateTime()? + ?TIME_TO_LIVE))?{
          ???cache_.remove(
          " chinaweather " );
          ???weather?
          = ? null ;
          ??}

          ??
          if ?(weather? == ? null )?{
          ???
          synchronized ?(cache_)?{
          ????weather?
          = ?parserWeather();
          ????cache_.put(
          " chinaweather " ,?weather);
          ???}
          ??}

          ??
          return ?weather;
          ?}


          posted @ 2007-03-08 06:56 konhon 優(yōu)華 閱讀(2231) | 評(píng)論 (0)編輯 收藏

          ?

          import ?org.htmlparser.Node;
          import ?org.htmlparser.NodeFilter;
          import ?org.htmlparser.Parser;
          import ?org.htmlparser.filters.TagNameFilter;
          import ?org.htmlparser.tags.TableTag;
          import ?org.htmlparser.util.NodeList;

          /**
          ?*?<br>
          ?*?標(biāo)題:?<br>
          ?*?功能概要:?<br>
          ?*?版權(quán):?cityyouth.cn?(c)?2005?<br>
          ?*?公司:上海城市青年網(wǎng)?<br>
          ?*?創(chuàng)建時(shí)間:2005-12-21?<br>
          ?*?修改時(shí)間:?<br>
          ?*?修改原因:
          ?*?
          ?*?
          @author ?張偉
          ?*?
          @version ?1.0
          ?
          */
          public ? class ?TestYahoo?{
          ????
          public ? static ? void ?testHtml()?{
          ????????
          try ?{
          ????????????String?sCurrentLine;
          ????????????String?sTotalString;
          ????????????sCurrentLine?
          = ? "" ;
          ????????????sTotalString?
          = ? "" ;
          ????????????java.io.InputStream?l_urlStream;
          ????????????java.net.URL?l_url?
          = ? new ?java.net.URL(
          ????????????????????
          " http://sports.sina.com.cn/iframe/nba/live/ " );
          ????????????java.net.HttpURLConnection?l_connection?
          = ?(java.net.HttpURLConnection)?l_url
          ????????????????????.openConnection();
          ????????????l_connection.connect();
          ????????????l_urlStream?
          = ?l_connection.getInputStream();
          ????????????java.io.BufferedReader?l_reader?
          = ? new ?java.io.BufferedReader(
          ????????????????????
          new ?java.io.InputStreamReader(l_urlStream));
          ????????????
          while ?((sCurrentLine? = ?l_reader.readLine())? != ? null )?{
          ????????????????sTotalString?
          += ?sCurrentLine;
          ????????????}
          ????????????System.out.println(sTotalString);

          ????????????System.out.println(
          " ==================== " );
          ????????????String?testText?
          = ?extractText(sTotalString);
          ????????????System.out.println(testText);
          ????????}?
          catch ?(Exception?e)?{
          ????????????e.printStackTrace();
          ????????}

          ????}

          ????
          /**
          ?????*?抽取純文本信息
          ?????*?
          ?????*?
          @param ?inputHtml
          ?????*?
          @return
          ?????
          */
          ????
          public ? static ?String?extractText(String?inputHtml)? throws ?Exception?{
          ????????StringBuffer?text?
          = ? new ?StringBuffer();

          ????????Parser?parser?
          = ?Parser.createParser( new ?String(inputHtml.getBytes(),
          ????????????????
          " 8859_1 " ),? " 8859-1 " );
          ????????
          // ?遍歷所有的節(jié)點(diǎn)
          ????????NodeList?nodes? = ?parser.extractAllNodesThatMatch( new ?NodeFilter()?{
          ????????????
          public ? boolean ?accept(Node?node)?{
          ????????????????
          return ? true ;
          ????????????}
          ????????});
          ????????Node?node?
          = ?nodes.elementAt( 0 );
          ????????text.append(
          new ?String(node.toPlainTextString().getBytes( " 8859_1 " )));
          ????????
          return ?text.toString();
          ????}

          ????
          /**
          ?????*?讀取文件的方式來(lái)分析內(nèi)容.?filePath也可以是一個(gè)Url.
          ?????*?
          ?????*?
          @param ?resource
          ?????*????????????文件/Url
          ?????
          */
          ????
          public ? static ? void ?test5(String?resource)? throws ?Exception?{
          ????????Parser?myParser?
          = ? new ?Parser(resource);

          ????????
          // ?設(shè)置編碼
          ????????myParser.setEncoding( " GBK " );
          ????????String?filterStr?
          = ? " table " ;
          ????????NodeFilter?filter?
          = ? new ?TagNameFilter(filterStr);
          ????????NodeList?nodeList?
          = ?myParser.extractAllNodesThatMatch(filter);
          ????????TableTag?tabletag?
          = ?(TableTag)?nodeList.elementAt( 11 );
          ????????????
          ????????????System.out.println(tabletag.toHtml());
          ????????????
          ????????????System.out.println(
          " ============== " );

          ????}

          ????
          /*
          ?????*?public?static?void?main(String[]?args)?{?TestYahoo?testYahoo?=?new
          ?????*?TestYahoo();?testYahoo.testHtml();?}
          ?????
          */
          ????
          public ? static ? void ?main(String[]?args)? throws ?Exception?{
          ????????test5(
          " http://sports.yahoo.com/nba/scoreboard " );
          ????}
          }
          posted @ 2007-03-08 06:50 konhon 優(yōu)華 閱讀(1602) | 評(píng)論 (0)編輯 收藏

               摘要: 最近搞一個(gè)扣網(wǎng)頁(yè)內(nèi)容的SessionBean,需要模擬客戶端post提交,然后得到servlet返回的結(jié)果。采用Jakarta的HttpClient API解決之.HttpClient擴(kuò)展和增強(qiáng)了標(biāo)準(zhǔn)java.net包,是一個(gè)內(nèi)容廣泛的代碼庫(kù),功能極其豐富,能夠構(gòu)造出各種使用HTTP協(xié)議的分布式應(yīng)用,或者也可以嵌入到現(xiàn)有應(yīng)用,為應(yīng)用增加訪問(wèn)HTTP協(xié)議的能力 要求:1:CLASSPATH中有...  閱讀全文
          posted @ 2007-03-07 21:51 konhon 優(yōu)華 閱讀(3781) | 評(píng)論 (0)編輯 收藏


          服務(wù)器:
          1.jsp
          <body>
          <form name="_ctl0" method="post" action="TestFileManager.aspx" id="_ctl0" enctype="multipart/form-data">
          <input type="hidden" name="__VIEWSTATE" value="dDwyNTIzNjA5NDU7Oz7rsE3eBYzQHDVtl+aTn96MvQW6PQ==" />
          <p>
          <input name="uploadfile1" id="uploadfile1" type="file" size="49" />
          <input type="submit" name="Button1" value="?" id="Button1" />
          </p>
          <p>
          <span id="Label1" style="width:459px;"></span>
          </p>
          <!-- Insert content here -->
          </form>
          </body>
          客戶端:
          首先創(chuàng)建一個(gè)到服務(wù)器http的請(qǐng)求
          HttpRequest request = new HttpRequest("http://服務(wù)器/1.jsp");
          第一次使用的是GET方式
          request.setMethod("GET");
          緊接著進(jìn)行一些請(qǐng)求的屬性設(shè)置
          request.setRequestHeader("Cache-Control", "no-cache");
          這里保持連接,因?yàn)楹竺孢€要發(fā)送數(shù)據(jù)到服務(wù)器呢
          request.setRequestHeader("Connection", "Keep-Alive");
          下面是一些無(wú)關(guān)緊要的屬性設(shè)置了。
          request.setRequestHeader("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
          request.setRequestHeader("Accept-Encoding", "gzip, deflate");
          request.setRequestHeader("Accept-Language", "en-au");
          request.setRequestHeader("Referer", "http://服務(wù)器/1.jsp");
          request.setRequestHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3215; .NET CLR 1.0.3705)");
          構(gòu)造好了連接請(qǐng)求,然后連接
          request.connect();
          緊接著提取Cookie值,在后文的post中可以用到。
          String strCookie = request.getResponseHeader("Set-Cookie");
          strCookie = strCookie.substring(0,strCookie.indexOf(";"));
          下面通過(guò)循環(huán)查找,提取__VIEWSTATE的值
          for ( int i = 0; i < nlist.getLength(); i++) {
          node = nlist.item(i);
          strName = getNodeAttributeValue(node,"name");
          if ( strName.equals("__VIEWSTATE") ) {
          strValue = getNodeAttributeValue(node,"value");
          break;
          }
          }
          往服務(wù)器組織發(fā)送數(shù)據(jù)
          DataOutputStream dos = new DataOutputStream(request.getOutputStream());
          dos.writeBytes("-----------------------------"+strBoundary);//這是每個(gè)要被發(fā)送數(shù)據(jù)間的間隔
          dos.writeBytes(" Content-Disposition: form-data; name="__VIEWSTATE"");
          dos.writeBytes(" "+strValue);
          dos.writeBytes(" -----------------------------"+strBoundary);
          這里面是發(fā)送文件的部分
          dos.writeBytes(" Content-Disposition: form-data; name="uploadfile1"; filename="" + strFileName + """);
          dos.writeBytes(" Content-Type: text/xml");
          dos.writeBytes(" ");
          dos.writeBytes(new String(data));
          dos.writeBytes(" -----------------------------"+strBoundary);
          dos.writeBytes(" Content-Disposition: form-data; name="Button1"");
          dos.writeBytes(" 上傳");
          dos.writeBytes(" -----------------------------"+strBoundary+"--");
          dos.writeBytes(" ");
          dos.close();
          posted @ 2007-03-07 20:14 konhon 優(yōu)華 閱讀(4274) | 評(píng)論 (1)編輯 收藏

          2007年1月30日 #

               摘要: 2?/**???3??*?//FileOperate.java??4??*?文件的各種操作??5??*?楊彩?http://blog.sina.com.cn/m/yangcai??6??*?文件操作?1.0??7??*/???8????9?//package?common;??10???11?import?java.io.*;??12???13?public?class?FileOperate?1...  閱讀全文
          posted @ 2007-01-30 06:25 konhon 優(yōu)華 閱讀(1176) | 評(píng)論 (0)編輯 收藏

          2006年12月17日 #

          最近在項(xiàng)目中使用 Spring Hibernate 進(jìn)行開(kāi)發(fā),有感于 Criteria 比較好用,在查詢方法設(shè)計(jì)上可以靈活的根據(jù) Criteria 的特點(diǎn)來(lái)方便地進(jìn)行查詢條件的組裝。所以現(xiàn)在對(duì) Hibernate Criteria 深入研究一下。《 Hibernate Reference 》及網(wǎng)上其它一些資料對(duì) Criteria 已經(jīng)做了很多介紹。本文主要是從 Criteria 的結(jié)構(gòu)入手來(lái)進(jìn)行分析。

          ?????? 如圖 1 Hibernate 設(shè)計(jì)了 CriteriaSpecification 作為 Criteria 的頂級(jí)接口,其下面提供了 Criteria DetachedCriteria

          Criteria DetachedCriteria 的主要區(qū)別在于創(chuàng)建的形式不一樣, Criteria 是在線的,所以它是由 Hibernate Session 進(jìn)行創(chuàng)建的;而 DetachedCriteria 是離線的,創(chuàng)建時(shí)無(wú)需 Session DetachedCriteria 提供了 4 個(gè)靜態(tài)方法 forClass(Class) forEntityName(Name) 進(jìn)行 DetachedCriteria 實(shí)例的創(chuàng)建。 Spring 的框架提供了

          getHibernateTemplate().findByCriteria(detachedCriteria) 方法可以很方便地根據(jù)

          DetachedCriteria 來(lái)返回查詢結(jié)果。

          如圖 1 Criteria DetachedCriteria 均可使用 Criterion Projection 設(shè)置查詢條件。可以設(shè)置 FetchMode( 聯(lián)合查詢抓取的模式 ) ,設(shè)置排序方式。對(duì)于 Criteria 還可以設(shè)置 FlushModel (沖刷 Session 的方式)和 LockMode (數(shù)據(jù)庫(kù)鎖模式)。

          下面就對(duì) Criterion Projection 進(jìn)行詳細(xì)說(shuō)明。

          ???????

          1

          ?

          ?????? Criterion Criteria 的查詢條件。

          Criteria 提供了 add(Criterion criterion) 方法來(lái)添加查詢條件。圖 2 Criterion 的結(jié)構(gòu)圖。 Criterion 接口的主要實(shí)現(xiàn)包括: Example Junction SimpleExpression 。而 Junction 的實(shí)際使用是它的兩個(gè)子類 conjunction disjunction ,分別是使用 AND OR 操作符進(jìn)行來(lái)聯(lián)結(jié)查詢條件集合。

          Criterion 的實(shí)例可以通過(guò) Restrictions 工具類來(lái)創(chuàng)建, Restrictions 提供了大量的靜態(tài)方法,如 eq (等于)、 ge (大于等于)、 between 等來(lái)方法的創(chuàng)建 Criterion 查詢條件

          SimpleExpression 實(shí)例)。除此之外, Restrictions 還提供了方法來(lái)創(chuàng)建 conjunction disjunction 實(shí)例,通過(guò)往該實(shí)例的 add(Criteria) 方法來(lái)增加查詢條件形成一個(gè)查詢條件集合。

          至于 Example 的創(chuàng)建有所不同, Example 本身提供了一個(gè)靜態(tài)方法 create(Object entity) ,即根據(jù)一個(gè)對(duì)象(實(shí)際使用中一般是映射到數(shù)據(jù)庫(kù)的對(duì)象)來(lái)創(chuàng)建。然后可以設(shè)置一些過(guò)濾條件:

          Example exampleUser =Example.create(u)

          .ignoreCase() // 忽略大小寫(xiě)

          .enableLike(MatchMode.ANYWHERE);

          // 對(duì) String 類型的屬性,無(wú)論在那里值在那里都匹配。相當(dāng)于 %value%

          ?
          2

          ??????

          Project 主要是讓 Criteria 能夠進(jìn)行報(bào)表查詢,并可以實(shí)現(xiàn)分組。 Project 主要有 SimpleProjection ProjectionList Property 三個(gè)實(shí)現(xiàn)。其中 SimpleProjection ProjectionList 的實(shí)例化是由內(nèi)建的 Projections 來(lái)完成,如提供的 avg count max min sum 可以讓開(kāi)發(fā)者很容易對(duì)某個(gè)字段進(jìn)行統(tǒng)計(jì)查詢。

          ?????? Property 是對(duì)某個(gè)字段進(jìn)行查詢條件的設(shè)置,如通過(guò)

          ????? Porperty.forName(“color”).in(new String[]{“black”,”red”,”write”}); 則可以創(chuàng)建一個(gè) Project 實(shí)例。通過(guò) criteria add(Project) 方法加入到查詢條件中去。

          ?
          3

          ??????

          ?????? 使用 Criteria 進(jìn)行查詢,主要要清晰的是 Hibernate 提供了那些類和方法來(lái)滿足開(kāi)發(fā)中查詢條件的創(chuàng)建和組裝,其結(jié)構(gòu)層次如何。這樣使用起來(lái)便可得心應(yīng)手。

          posted @ 2006-12-17 03:18 konhon 優(yōu)華 閱讀(1539) | 評(píng)論 (1)編輯 收藏

          僅列出標(biāo)題  下一頁(yè)
          主站蜘蛛池模板: 九龙城区| 健康| 河南省| 靖西县| 怀化市| 镇原县| 桦南县| 万荣县| 同江市| 二手房| 闻喜县| 孟连| 毕节市| 蓝山县| 堆龙德庆县| 宣城市| 瓦房店市| 禄劝| 永德县| 淅川县| 康保县| 新丰县| 淮滨县| 宣武区| 龙口市| 弥渡县| 拜城县| 濉溪县| 长寿区| 隆尧县| 宝清县| 化州市| 绥德县| 康乐县| 麦盖提县| 奈曼旗| 保定市| 连南| 永康市| 仪征市| 固安县|