<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    GONE WITH THE WIND

    --tomorrow is another day

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      30 隨筆 :: 19 文章 :: 0 評論 :: 0 Trackbacks

    #

    1.作用的范圍不同:

    1)inverse :<set/>,<map/>,<list/>,<array/>,<bag/>

    2)cascade :<many-to-one>,<one-to-one/>,<set/>,<map/>,<list/>,<array/>,<bag/>.

    2.執行策略不同

    1)inverse :首先判斷集合的變化情況,然后針對變化執行相應的處理。

    2)cascade :直接對集合中的每個元素執行相應的處理。

    3.執行的時機不同

    1)inverse :在執行SQL語句之前判斷是否要執行該SQL語句。

    2)cascade :在主控方發生操作時用來判斷是否進行級聯操作。

    4.執行的目標不同

    1)inverse :對于<one-to-many>處理被管理表,<many-to-many/>處理中間表。

    2)cascade :都只只對被關聯表。

    總結:書上說了inverse 一對多的時候最好把多的一方設置成false由一的一方來控制;cascade盡量別使,進行顯示的添加刪除。

    posted @ 2009-03-30 16:46 張永耀 閱讀(176) | 評論 (0)編輯 收藏

    構造這樣一個例子,在測試過程中來說明一些Hibernate的高級配置及其相關機制:
    有三個類:Category.java,Prodcuct.java,ConfigurationTest.java,其中第三個類是用來測試的。
    Category.java代碼:
           

    package unsaved_value;    
    import ......    
    public class Category {    
        private Integer id;    
        private String name;    
        private String description;    
        private Set products;    
        public Category(){    
             id=null;    
             name=null;    
            description=null;    
            products=new HashSet ();    
         }    
         public void addProduct(Product p){    
             products.add(p);    
        }    
         //**********setter and getter    
        ........    
    }   


    Product.java代碼:


    package unsaved_value;      
    public class Product {      
        private Integer id;      
        private String name;      
        private Category category;      
        private String description;      
        public Product(){     
             
        }      
         //*******getter and setter      
         .........      
    }      

    ConfigurationTest.java

    public void testSave()throws Exception{    
            Category category=new Category();    
            category.setName("java編程書籍2");    
            category.setDescription("編程經典書籍2");    
            Product pro=new Product();    
            pro.setName("java編程思想2");    
            pro.setDescription("第四版中文版2");     
            pro.setCategory(category);    
            category.addProduct(pro);    
            Transaction tx=session.beginTransaction();    
            assert (session!=null):("session is null");    
            session.save(category);    
            tx.commit();    
        }    

         
    Category代表產品目錄,而Product代表產品,顯然Category與Product是一對多的關系。Hibernate在映射一對多關系時,有兩種方式,一種是單向一對多,一種是雙向關系。兩者相比,雙向一對多的好處體現在兩方面:首先,也是很明顯的一點,由于是雙向關聯,我們在實際業務邏輯時將更方便,例如我們可以檢索一個Category下的所有Product,同時還可以檢索出Product屬于哪個。其次,雙向關系相對單向關系而言,在數據庫的訪問方面更有優勢。這一點留在后面講inverse時講
    。雙向關聯比單向關聯唯一的”劣勢“,就在于雙向關聯需要比單向關聯多寫一個映射文件,這不問題。使用雙向關聯實現這兩個類同數據庫的映射:

    Category.hbm.xml:  
    version="1.0" encoding="UTF-8"?>  

    " <hibernate-mapping package="unsaved_value">  
       <class name="Category" table="category">  
         <id name="id" column="id">  
           <generator class="native">generator>  
         id>  
         
         <property name="name" column="name"/>  
         <property name="description" column="description"/>


         <set name="products" table="product" lazy="true" inverse="true" cascade="all">  
             <key column="category"/>  
                <one-to-many class="Product"/>  
         set>  
         
       class>  
    hibernate-mapping>  
      
    Product.hbm.xml:


    version="1.0" encoding="UTF-8"?>    
    "
    <hibernate-mapping package="unsaved_value">    
    <class name="Product" table="product">    
         <id name="id" column="id" unsaved-value="null">    
             <generator class="native">generator>    
         id>    
             
         <property name="name" column="name"/>    
         <property name="description" column="description"/>    
           
         <many-to-one name="category"    
                      column="category"     
                      class="Category"    
         />    
       class>    
    hibernate-mapping>    
            
    現在把這個例子所牽涉到的知識一一展開:
    一.inverse
        該詞的譯意是“反轉”,反轉什么——反轉控制端,這項配置決定了由關聯雙方中的哪一方來維持關聯關系(在數據庫中表現為外鍵約束)。上述配置中,在Category.hbm.xml中將inverse設置為true,意思是說“我需要反轉(控制端)”,反轉的結果是由對方即Product來維持關聯關系。用單向關聯更容易說明”維持關聯關系“是什么意思:考慮用單向關系來實現這個映射關系的情況,即由Category關聯到Product,考慮下面的代碼:

    Product p=new Product();  
    ..setXXX  
    Category c=new Category();  
    ..設置Category的屬性  
    c.addProduct(p);//建立起了c和p的關聯關系  
    session.save(c);  

    會執行三條SQL語句:兩條插入語句,分別插入c和p,然后還有一條update語句建立起c和p的關聯(更新p的外鍵)。上面,我們說由Category端控制關聯,因此p.setCategory(c)這樣一句話是沒用的,它并不會導致在插入p的時候就設置p的外鍵以建立起兩者的關聯關系,從而節省一條update語句。同時我們還會看到,如果在數據庫模式中將p的外鍵設置成非空,這些代碼將不能執行,因為在插入p時,由于c和p的關聯關系還未建立起來,因此p的外鍵為空。回到雙向關聯上來,為了更清楚地明白inverse在雙向關聯中到底起什么作用,我們分別將其值設為true和false,看看打印出的的SQL有何區別:

    inverse=true時的打印結果:

    Hibernate: insert into category (name, description) values (?, ?)  
    Hibernate: insert into product (name, description, category) values (?, ?, ?)   
    inverse=false時的打印結果:

    Hibernate: insert into category (name, description) values (?, ?)    
    Hibernate: insert into product (name, description, category) values (?, ?, ?)    
    Hibernate: update product set category=? where id=?   
           為什么inverse=true時會比inverse=false時少執行一條SQL語句?這是由控制端的不同造成的。前者說"我要反轉控制,由Product來控制關聯",因此在將p對象insert時,p已經設置了其category字段,從而建立了關聯關系,而后者說"我不反轉控制,由我自己來控制關聯",因此在將p對象insert后,c為了維持兩者的關聯,還要去執行一次update,以更新p的外鍵,從而建立起兩者的關聯關系。
    結論:對于一對多雙向關系,始終在“一”那一方將其inverse設置成true,這樣會提高性能。

    二.cascade
       級聯。當關聯的"一"方進行某種動作(更新,刪除)時,"多"方即使沒有顯式地進行編碼,它也會自動進行同樣的動作。cascade的可選值有:
    all : 所有情況下均進行關聯操作。即是save-update + delete
    none:所有情況下均不進行關聯操作。這是默認值。
    save-update:在執行save/update/saveOrUpdate時進行關聯操作。
    delete:在執行delete時進行關聯操作。
    all-delete-orphan:A:級聯save-update B級聯delete C:刪除所有孤兒項(orphan孤兒)。先看看父子關系,例如在Customer和Order的模型中,這兩者便是父子關系,當一個Customer的生命周期決定Order的生命周期,如果一個Customer不在了,其相關的Order繼續存在是毫無業務意義的。刪除所有孤兒項的意思即是,刪除所有與父對象失去關聯關系的子對象。

    三.lazy
        是否延遲加載。一般來說,應該延遲加載,即將lazy設為true。延遲加載的相關點很多,這在另外的學習筆記中總結。

    四.unsaved-value
        以上是"一"方的重要配置,再看看"多"方的一個重要配置:unsaved-value,就像上面Product.hbm.xml中的設置那樣,這一項在id的配置中設置。這一設置是與級聯一起工作的。關于這一點,robbin講的很清楚:
    當你顯式的使用session.save()或者session.update()操作一個對象的時候,實際上是用不到unsaved-value 的。某些情況下(父子表關聯保存),當你在程序中并沒有顯式的使用save或者update一個持久對象,那么Hibernate需要判斷被操作的對象究竟是一個已經持久化過的持久對象,是一個尚未被持久化過的內存臨時對象。例如:
           Session session = ...;
    Transaction tx = ...;  
    Parent parent = (Parent) session.load(Parent.class, id);  
    Child child = new Child();  
    child.setParent(parent);  
    child.setName("sun");  
    parent.addChild(child);  
    s.update(parent);  
    s.flush();  
    tx.commit();  
    s.close();  
         在上例中,程序并沒有顯式的session.save(child); 那么Hibernate需要知道child究竟是一個臨時對象,還是已經在數據庫中有的持久對象。如果child是一個新創建的臨時對象(本例中就是這種情況),那么Hibernate應該自動產生session.save(child)這樣的操作,如果child是已經在數據庫中有的持久對象,那么 Hibernate應該自動產生session.update(child)這樣的操作。因此我們需要暗示一下Hibernate,究竟 child對象應該對它自動save還是update。在上例中,顯然我們應該暗示Hibernate對child自動save,而不是自動 update。那么Hibernate如何判斷究竟對child是save還是update呢?它會取一下child的主鍵屬性 child.getId() ,這里假設id是 java.lang.Integer類型的。如果取到的Id值和hbm映射文件中指定的unsave-value相等,那么Hibernate認為 child是新的內存臨時對象,發送save,如果不相等,那么Hibernate認為child是已經持久過的對象,發送update。unsaved-value="null" (默認情況,適用于大多數對象類型主鍵 Integer/Long/String/...)
    當Hibernate取一下child的Id,取出來的是null(在上例中肯定取出來的是null),和unsaved-value設定值相等,發送save(child)
    當Hibernate取一下child的id,取出來的不是null,那么和unsaved-value設定值不相等,發送update(child)
       unsaved-value的可選配置有:
    none,any,null
    unsaved-value="none"和unsaved-value="any"主要用在主鍵屬性不是通過Hibernate生成,而是程序自己setId()的時候。unsaved-value="none"和unsaved-value="any"究竟有什么含義了。如果你非要用assigned不可,那么繼續解釋一下:
    unsaved-value="none" 的時候,由于不論主鍵屬性為任何值,都不可能為none,因此Hibernate總是對child對象發送update(child)
    unsaved-value="any" 的時候,由于不論主鍵屬性為任何值,都肯定為any,因此Hibernate總是對child對象發送save(child)
          大多數情況下,可以避免使用assigned,只有當你使用復合主鍵的時候不得不手工setId(),這時候需要你自己考慮究竟怎么設置unsaved-value了,根據你自己的需要來定。
          關于為什么不要使主鍵帶有義務意義,robbin的解釋很清楚:還是以上面的例子打比方,如果我們將Category的某一個性質(比如產品序號或者名稱)作為主鍵,如果后來由于業務需要,我們把這個性質改了,那將不可僻免地要去修改與這個對象相關聯的所有數據的外鍵,而如果我們只要代理主鍵,這個問題就可完全僻免。

    posted @ 2009-03-30 16:06 張永耀 閱讀(318) | 評論 (0)編輯 收藏

    今天在寫程序的時候發現了一個很奇怪的問題“ResultSet can not re-read row data for column”,用google一搜,原來是微軟公司的驅動的兼容性不太好。有熱心人總結了微軟驅動的缺點:(1)如果采用jdbc-odbc驅動,那么就必須按照查詢順序來一次讀取(不論有沒有image或text,ntext類型)(2)如果采用微軟提供的ms sql server jdbc driver,如果查詢語句中,不存在image或text,ntext類型字段,那么可以按照無序獲取(3)如果采用微軟提供的ms sql server jdbc driver,如果查詢語句中,存在image或text,ntext類型字段,那么就必須按照順序讀取,否則就會報告Driver]ResultSet can not re-read row data for column之類的錯誤(4)如果想不查詢語句中有沒有image或text,,ntext類型字段,都可以不按照順序獲取,或重復獲取。那么就必須更換驅動,改用第三方的。 最后,我改用了第三方的驅動。測試成功。
    posted @ 2009-03-27 14:25 張永耀 閱讀(309) | 評論 (0)編輯 收藏

    用delphi和VB實現瀏覽器中超長文件的上傳
     

    摘 要 本文通過delphi的Tihttp控件,將超大文件分割成幾個小文件,通過構造的表單數據流,

                直接發送到接收數據網頁,由vb編寫的服務器端進行文件接收和還原

    一、問題的提出:

    本單位在開發課件生成系統時,需要通過瀏覽器向服務器指定目錄傳送大的音、視頻文件。在微軟asp中未提供相應的控件,asp.net雖然提供了form表單中的file控件進行文件上傳,但對上傳的文件有長度限制,文件長度大于50M上傳會失敗,而微軟基于安全考量,file控件中的文件名在運行期間只讀,這樣利用微軟提供的控件向服務器端上傳長度超過50M的文件變為不可行,必須另劈蹊徑。

    二、解決方案

    delphi以其強大的控件集,快速的RAD開發,深得程序開發人員的青睞,其最新控件集Indy,集成了大部分流行的Internet協議,包括TCPUDPDNSICMPFINGERFTPGOPHERHTTPPOP3SMTPTELNETWHOIS,而瀏覽器的傳輸協議為http。這樣我們可以利用delphi7中的TIHTTP控件,將數據打包后上傳到服務器端。基本思路為:開發兩部分功能程序,一個為ActiveX控件,嵌入到網頁中,負責將客戶端本地上傳文件分解成n個數據包,每個數據包直接編碼成“multipart/form-data”格式的表單信息,依次調用TIhttp控件的post方法向服務器端發送信息。另一個為服務器端的com組件,接受發送過來的原始信息,將數據包拼接還原成文件保存到服務器的指定目錄中。

    三、技術要點:

        1Delyhi 7開發Active X控件要點:選擇新建項目→Active x標簽→Active Form→填入控件名可快速搭建一個Acfire X控件架構,產生一個表單和一個框架代碼文件。

    2.上傳Active x控件設計要點:①表單控件中放置一個編輯控件、三個命令按鈕、一個進度條控件、一個文本標簽控件、一個文件對話框控件。編輯控件用來放置上傳文件名。一個瀏覽按鈕打開文件選擇對話框,選擇上傳文件;進度條控件顯示上傳文件進度;文本標簽顯示上傳文件百分比,取消按鈕可中斷文件上傳。

    ②項目包含兩個代碼文件,其中一個文件用來將上傳文件拆分成小數據包。其關鍵代碼如下:

        for y:=0 to filenum  do

           begin

             if y=0  then   //第一個包

                 begin

                if y <> filenum then

                      begin

                          for i:=1 to basenum do

                            begin

                               read(f,ch);

                               tempf:=chr(ch);

                               temp:=temp+tempf;

                              application.ProcessMessages;

                            end;

                        vflag:=postdata(vurl,vfilename,temp,'0');

                        end

                      else

                             begin

                             j:=0;

                                while not eof(f) do

                                begin

                                  read(f,ch);

                                tempf:=chr(ch);

                                temp:=temp+tempf;

                                j:=j+1;

                                application.ProcessMessages;

                      vflag:=postdata(vurl,vfilename,temp,'-2');

                    end;

                   end

                   else if y<> filenum then //中間包

                       begin

                          for i:=1 to basenum do

                            begin

                               read(f,ch);

                              tempf:=chr(ch);

                               temp:=temp+tempf;

                                application.ProcessMessages;

                            end;

                              vflag:=postdata(vurl,vfilename,temp,'1');

                      end

                   else  //最后一個包

                     begin

                            j:=0;

                            while not eof(f) do

                           begin

                             read(f,ch);

                             tempf:=chr(ch);

                             temp:=temp+tempf;

                             j:=j+1;

                              application.ProcessMessages;

                         end;

                       vflag:=postdata(vurl,vfilename,temp,'-1');

                     end;

           end;

    end;

    ③另一個文件用來將小數據包按照http格式封裝成二進制文件上傳數據流發送到指定的接收頁面(URL),數據流除必要的頭信息,包含兩個表單城,一個數據塊,其中一個表單域用來傳遞文件標記,用來區分本數據包是第一個包,中間包還是最后一個包,另一個表單域傳遞上傳文件名,其關鍵代碼如下:

       try

         filedata.Seek(0,sofrombeginning);

         tempstring:='';

         tempstring:=tempstring+'------------------------------7cf87224d2020a'+

             newline;

         tempstring:=tempstring+'Content-Disposition: form-data;name="vflag"'+newline;

         tempstring:=tempstring+''+newline;

         tempstring:=tempstring+vflag+newline;

         tempstring:=tempstring+''+newline;

         tempstring:=tempstring+''+newline;

         tempstring:=tempstring+'Content-Disposition: form-data; name="editfilename"; filename="'+infile+'"'+newline;

         tempstring:=tempstring+'Content-Type: application/octet-stream'+newline;

         tempstring:=tempstring+''+newline;

         fillchar(temparray,sizeof(temparray),#0);

         strpcopy(temparray,tempstring);

         request.Write(temparray,length(tempstring));

         request.seek(0,sofromend);

         request.CopyFrom(filedata,filedata.size);

         tempstring:='';

         tempstring:=tempstring+''+newline;

         tempstring:=tempstring+'------------------------------7cf87224d2020a--'

              +newline;

         fillchar(temparray,sizeof(temparray),#0);

         strpcopy(temparray,tempstring);

         request.write(temparray,length(tempstring));

         try

           http.Post(url,request,response);

           if pos('成功',response.datastring)<>0 then

              flag:=1

         end.

    End.

    ④本ActiveX控件特色:可以實時顯示上傳進度,并能隨時中斷文件的上傳,上傳頁面畫面如圖所示,可不能隨時中斷文件上傳,即應用程序能隨時從循環語句中跳出,在循環語句中使用了ayydicdition Process Messages語句,該語句用來監聽和處理系統消息這樣就有效避免了文件上傳時,不能進行系統的其它操作。

    3.用VB6.0開發服務器端接收文件的Activeex dll,主要利用VB6.0強大的網頁操作功能,引用庫文件microsoft Active sever Page object library。其中包含有asp對象Asp library request。創建一個接收函數load,使用request對象讀取上傳給接收頁面的二進制數據流,分離出上傳標志、上傳文件名以及文件內容,根據上傳標志將分段傳送來的文件內容拼接成一個完整的文件,保存到指定目錄。

    四、幾點說明

        1.本程序在操作系統為Win98 Win2000的客戶端機器,IIS服務器端為Win 2000的環境下調試通過;

    2.將upfile.htmupload.aspmyget.dllupfileproj1.ocx文件放置到IIS服務之虛擬目錄upfile下(缺省目錄為C:"Inetpub"unnroot"upfile);

    3.修改upfile.htmcodebase屬性(缺省為http://11.68.17.80/upfile/upfileproj1.ocx)中的IP地址為服務器端地址;

    4.修改delphi工程文件upfileprojl中的upfilelmpl1文件中的Button2 click事件中的vulstring=’http://11.68.17.80/upfile/upload.asp’一行數據,將其中的IP地址轉接為服務器端地址,重新編譯后將upfrleprojl.ocx放置到虛擬目錄下;

    5.上傳文件在服務器端的默認保存目錄為c:"temp;

    6.須手工注冊myget.dll,命令語句為regsvr32  C:"inetpub"wwwroot"upfile"myget.dll

    7.覽器中敲擊網站地址執行,缺省地址為http://11.68.17.80/upfile/upfile.htm
    posted @ 2009-03-27 08:48 張永耀 閱讀(489) | 評論 (0)編輯 收藏

    我們的產品中間件的啟動是由批處理文件開始,這就導致,始終有個DOS窗口,來顯示服務器的運行情況。可客戶不樂意啊:他們就想萬一誰不小心把那窗口給關了,損害了數據,那問題可就大了!這個問題確實是挺有價值的。
    首先,我們考慮WINDOWS環境吧,我不認為WINDOWS環境下和*NIX環境下的實現有很大差別。想到以前看到的,聽到的,再加上自己的經驗,大概有這么集中方式:
  • 包裝bat文件為exe文件,然后以后臺服務的形式注冊
  • 利用windows自帶的Wscript.Shell
  • 寫個Swing界面小程序,利用多線程,啟動應用服務,把DOS窗口替換成應用窗口。
  • 但我們需要考慮另外一點:我們的應用在運行的時候,會向dos窗口輸出一些出來的一些信息,這些信息在很多情況下都是很有用的。現在如果把DOS窗口隱藏了,那么那些信息我把他們存放到哪兒呢?我想最好還是以文件的形式保存起來,將來如有問題還可以追查!
    現在考慮各種實現方式。包裝為exe的形式,也只能在windows環境下運行,并且需要額外的工具;Swing界面小程序這個其實是最可行的,但我這個人比較懶,比較討厭寫界面;利用windows自帶的Wscript.Shell,自然也只能依賴于windows環境,后來我想了下,其實這個方案可以和swing界面那個方案有不少東西是可以公用的。最后決定,為了簡單期間,偶就先用Wscript.Shell,來做測試了。
    實際的情況大致是:
  • 應用服務的啟動腳本是/startup.bat 實際中我們可以使用vbs腳本:
  • dim ws
    Set ws = CreateObject("Wscript.Shell")
    ws.run "cmd /c /startup.bat >> myServer.log" ,vbhide
    通過這樣簡單的設置,我們可以做到隱藏DOS窗口,但是,如果我們的應用一下子運行好幾個月,那我們的日志文件myServer.log的日積月累地,就太大了。我們在查找問題的時候,也很不容易!所以我們應該想法子把日志文件myServer.log,按時間或者按大小分開存儲。這也是我們應用服務器日志的做法。所以,我們需要再做一步中間處理,想想看"appRoot/startup.bat"這一步,我們在程序當中還是可以獲得它的輸出結果的。看下面java程序:
    package nc.client.StartupUtil;

    import java.lang.ProcessBuilder;
    import java.util.Vector ;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.FileWriter;
    import java.io.BufferedWriter;
    import java.util.Collections ;

    public class NC50StartUtil
    {

    public static final String logFileNamePrefix = "ncconsolelogs";

    public static void main(String[] args)
    {
    ProcessBuilder processBuilder = new ProcessBuilder("cmd", "/C", args[0]+"/startup.bat");
    processBuilder.directory(new File(args[0]));
    Process process = null;
    try
    {
    process = processBuilder.start();
    BufferedReader datais =
    new BufferedReader(
    new InputStreamReader( process.getInputStream()));


    // 服務器日志目錄
    String serverLogDirName = args[0] + "/nclogs/server";
    File serverLogDir = new File (serverLogDirName);
    if (!serverLogDir.exists())
    {
    serverLogDir.mkdirs();
    }

    int maxFileIndex = getMaxFileIndex(serverLogDirName).intValue();
    File logFile = new File(serverLogDirName+"/ncconsolelogs.log");
    if (!logFile.exists())
    {
    logFile.createNewFile();
    }
    else
    {
    // 如果已經存在日志文件,則先把原來的文件歸檔,然后新創建一個日志文件
    StringBuffer oldFileName = new StringBuffer();
    oldFileName.append(serverLogDirName);
    oldFileName.append("/");
    oldFileName.append(logFileNamePrefix).append("[").append(maxFileIndex).append("].log");
    logFile.renameTo(new File(oldFileName.toString()));
    maxFileIndex++;
    //創建新的日志文件
    if (!logFile.exists())
    {
    logFile.createNewFile();
    }

    }

    BufferedWriter writer = new BufferedWriter(new FileWriter(logFile));

    // 文件的最大大小是2M
    int maxlength = 1024*1024*2;

    String c;
    while ((c = datais.readLine()) != null)
    {

    writer.write(c);
    writer.newLine();
    writer.flush();

    // 超過日志文件規定的大小了,則把日志文件歸檔,然后新創建一個日志文件
    if (logFile.length() > maxlength)
    {
    writer.close();
    StringBuffer oldFileName = new StringBuffer();
    oldFileName.append(serverLogDirName);
    oldFileName.append("/");
    oldFileName.append(logFileNamePrefix).append("[").append(maxFileIndex).append("].log");
    logFile.renameTo(new File(oldFileName.toString()));
    maxFileIndex++;

    // 創建新的日志文件
    if (!logFile.exists())
    {
    logFile.createNewFile();
    }
    writer =   new BufferedWriter(new FileWriter(logFile));
    }

    }
    }
    catch(IOException e)
    {
    e.printStackTrace ();
    }
    }

    public static Integer getMaxFileIndex(String ncconsolelogdirname)
    {
    File ncconsolelogdir = new File(ncconsolelogdirname);
    File[] ncconsolelogs = ncconsolelogdir.listFiles(new NcLogFileNameFilter(logFileNamePrefix));

    if (ncconsolelogs != null && ncconsolelogs.length > 0)
    {
    Vector v = new Vector();
    for (int i=0, len=ncconsolelogs.length; i startIndex)
    {
    String index = logFileName.substring (startIndex+1, endIndex);
    int ind = -1;
    try
    {
    ind = Integer.parseInt(index);
    }
    catch(Exception e)
    {

    }

    if (ind > 0)
    {
    v.add(ind);
    }
    }
    }
    if (v.size() > 0)
    {
    return Collections.max(v) + 1;
    }
    else
    {
    return 1;
    }
    }

    return 1;
    }
    }
    package nc.client.StartupUtil;

    import java.io.File;
    import java.io.FilenameFilter;

    // 一個簡單的文件名過濾類
    public class NcLogFileNameFilter implements FilenameFilter {

    private String fileNamePrefix = null;

    public NcLogFileNameFilter(String fileNamePrefix)
    {
    this.fileNamePrefix = fileNamePrefix;
    }

    public boolean accept(File dir, String name)
    {
    if (name.toLowerCase().startsWith(fileNamePrefix))
    {
    return true;
    }
    return false;
    }
    }
    之后,為了運行方便,我們把這兩個類編譯后打成可執行的jar包,例如ncstartuputil.jar。并修改vbs腳本為:
    dim ws
    Set ws = CreateObject("Wscript.Shell")
    ws.run "cmd /c java -jar ncstartuputil.jar E:/nchome_zhengshi" ,vbhide
    如果換做swing界面,其實僅僅需要寫另外一個Thread,thread的主體也正式上面static main方法主體,然后通過多線程,可以獲得原始start.bat批處理文件的輸出,并且把輸出的信息放到一個textarea里面顯示出來。:-)....
    posted @ 2009-03-26 17:16 張永耀 閱讀(739) | 評論 (0)編輯 收藏

    最近做在做一個項目,涉及到文件上傳的問題。 以前也做過文件上傳。但都是些小文件,不超過2M。 這次要求上傳1G以上的東西。 沒辦法找來資料研究了一下。 基于WEB的文件上傳可以使用FTP和HTTP兩種協議,用FTP的話雖然傳輸穩定,但安全性是個嚴重的問題,所以沒有考慮。 剩下只有HTTP。 在HTTP中有3種方式,PUT、WEBDAV、RFC1867,前2種方法不適合大文件上傳,在這里也不說了。
    確定使用RFC1867格式處理之后開始分析流行的上傳組件。看了N多代碼之后發現,目前無組件程序和一些COM組件都是使用Request.BinaryRead方法。一次性得到上傳的數據,然后分析處理。這就是為什么上傳大文件很慢的原因了,IIS超時不說,就算1G文件上去了,分析處理也得一陣子。 之后我把注意力放在國外商業組件上,比較流行的有Power-Web,AspUpload,ActiveFile,ABCUpload,aspSmartUpload,SA-FileUp。其中比較優秀的是ASPUPLOAD和SA-FILE,他們號稱可以處理2G的文件(SA-FILE EE版甚至沒有文件大小的限制),而且效率也是非常棒,難道編程語言的效率差這么多?(我的編程環境是VB6) 查了一些資料,覺得他們都是直接操作文件流。這樣就不受文件大小的制約。 真是個好方法。
    但老外的東西也不是絕對完美,ASPUPLOAD處理大文件后,內存占用情況驚人。1G左右都是稀松平常。我用的是3.0.0.3版。至于SA-FILE雖然是好東西但是破解難尋(郁悶死..) 失望之際,發現2款上傳組件,Lion.Web.UpLoadModule和AspnetUpload,都是.NET的,估計也是操作文件流。但是上傳速度和CPU占用率都不如老外的商業組件。
    做了個測試,LAN內傳1G的文件。ASPUPLOAD上傳速度平均是4.4M/s,CPU占用10-15,內存占用700M。SA-FILE也差不多這樣。而AspnetUpload最快也只有1.5M/s,平均是700K/s,CPU占用15-39,測試環境:PIII800,256M內存,100M LAN。我想AspnetUpload速度慢是可能因為一邊接收文件,一邊寫硬盤。資源占用低的代價就是降低傳輸速度。 但也不得不佩服老外的程序,CPU占用如此之低.....這樣2個.net的組件也被PASS.

    稍帶2個問題就是上傳進度和斷點續傳。
    顯示上傳進度比較簡單,主要是查詢用戶上傳的狀態,用Script顯示到瀏覽器中,至于無刷新顯示就要看腳本語言運用的熟練程度了。
    斷點續傳,HTTP方式是實現不了的,因為瀏覽器每次上傳文件都是從頭開始,沒有Range標簽。實現的方法只能用ActiveX。

    研究之后決定寫個CGI來處理文件上傳。 這樣可以不走IIS以免程序出錯影響網站訪問。小弟比較菜只能用VB6做,完成之后發現WIN CGI的效率簡直就是差的不能再差。索性寫個FILE SERVER,專門處理文件的上傳。但是現在遇到一個2個問題。
    一、用WINSOCK控件接收到的文本有亂碼 不知道是程序轉換時的錯誤還是WINSOCK本身垃圾,SO 換了PowerTCP的WINSOCK TOOL,情況有所好轉 亂碼沒那么多了.........準備換vb.net,直接操作socket,程序還沒做,不知道用.net接收會不會亂碼。再有就哭了。
    二、這個問題就比較初級了....接收到的文件流不能還原成文件..寒一個,

    最后就是如何高效處理文件流, 我想來想去也就只有2種方法,一是都放在內存里,然后一起處理, 二是一邊接收一邊寫文件。 但這2種方法都不盡如人意思
    posted @ 2009-03-26 17:00 張永耀 閱讀(125) | 評論 (0)編輯 收藏


    http://cydn.8k.com      http://cydn.8m.com     http://cydn.s5.com

    登陸修改地址:http://cydn.8k.com/cgi-bin/login

    http://cydn.8k.com/cgi-bin/login

    http://cydn.s5.com/cgi-bin/login


    1。  個人空間和Blog   http://zhoubing518.x.27h.org/

    也就是: http://www.27h.com/blog/html/03/143103.html

    支持Ftp上傳,地址:ftp.27h.com  最好用CutFtp工具上傳。用戶名密碼為登陸的用戶名和密碼

    支持Html解析,不能解析jsp,屬于WEB服務器。

    網站的信件內容如下:

         尊敬的 cydn 用戶你好!
        我是醬子家園的管理員!
    感謝您申請我們的免費主頁服務,您已經成為我們的用戶。
    ======================================================================
    您的FTP地址為 ftp://ftp.27h.com
    用戶名為 cydn
    目前空間大小為 50M 您的主頁地址為 http://cydn.27h.com

    您必須安裝FTP軟件,例如LEAPFTP CUTEFTP等

    2.    速度最快,最穩定的一個:  http://hi.baidu.com/zbzb  

    不能上傳自己的Html頁面.但有100M的照片庫  

    3.   個人空間   http://zb.s5.com    國外免費空間,支持Html .用戶登陸頁:http://www.s5.comhttp://www.s5.comhttp://www.s5.comhttp://www.s5.com    國外免費空間,支持Html .用戶登陸頁:http://www.s5.com

    登陸修改地址:http://zb.s5.com/cgi-bin/login

    4.   個人Blog  博客地址:http://zb66.139.com   您的用戶名:zb66  您的密碼:***
    手機登陸的WAP地址:http://zb66.m.139.com     頁面不是很好看,模版少。速度快,.net網站。

    5.  http://host.tomore.com   

    主機名:http://host.tomore.com/cydn/

    FTP:

    主機:host.tomore.com
    用戶名:cydn
    密碼:你的會員密碼.
    空間大小:50 M .

    Mysql:未開通,請升級為正式會員!

    5.  我申請的幾個免費域名

    我申請的域名:
    http://cydn.wyou.cn
    http://smys.9126.com
    http://smys.9126.com
    http://cydn.1www.cn/http://xacydn.9126.com
    圣博個人免費空間:
    http://cydn.home.sunbo.net

    6.  免費域名申請網址簡介:

    http://www.wyou.cn/reg/reg.asp   
    免費域名服務由萬游網提供

    http://www.xinfree.com/default.htm

    申請地址:http://www.008.net/free/

    申請網址:http://ew88.com/reg.asp

    申請地址:http://www.eee.cc/

    申請網址: http://www.chinese.cn.com/freedomain/
    CHINESE.cn.com 免費域名開始測試,域名長度要求在3至20個字符之間。 您可以注冊以下域名:
    yourname.chinese.cn.com
    yourname.163.cn.com
    yourname.263.cn.com
    yourname.sina.cn.com
    yourname.sohu.cn.com
    yourname.tom.cn.com
    快來搶注呀!

    申請網址: http://reg.900du.com/

    免費 ***.k6.cn域名!
    申請網址: http://jsyzt.k6.cn/reg/reg.asp

    申請網址:http://mycool.net/

    申請網址:http://my.k6.cn/reg/reg2.asp

    很不錯的免費域名,共27種后綴,例如:cc.ly/tv.ly/cn.ly/on.ly,快去申請吧!

    申請網址:
    http://tv.ly/

    可選擇的后綴有:   hk.ly   dj.md   ok.mu   n.md   w.md   hk.md   tea.ms   email.ly   cn.ly   jp.ly   kr.pn   cc.ly   tv.ly   co.kr.mw   co.kr.pn   name.md   kr.mw   to.tc   email.dj   blog.vg   on.ly   cc.la   cn.la   tw.la   jp4.jp   na.la   wa.la

    Lycos中國免費聊天室申請! 
    時間: 2004-07-12 21:08:37 | [<<] [>>]
    --------------------------------------------------------------------------------
        免費提供個人聊天室,申請簡單,只需在主頁添加一段html代碼即可,沒有廣告,速度尚可,但功能較少。

    申請網址: http://chat.lycos.com.cn/hkcn/code.html
    碧聊免費聊天室申請!
    --------------------------------------------------------------------------------
    免費提供支持10人的語音聊天室,速度快、功能強,如果需要更大在線人數可以購買收費服務。

    申請網址: http://www.bliao.com/help/help23.htm

    posted @ 2009-03-26 14:12 張永耀 閱讀(116) | 評論 (0)編輯 收藏

    閱讀全文
    類別:數據庫 查看評論
    文章來源:http://hi.baidu.com/zbzb/blog/item/286f8b5438a4bf183b293556.html
    posted @ 2009-03-26 13:21 張永耀 閱讀(50) | 評論 (0)編輯 收藏

    閱讀全文
    類別:免費資源 查看評論
    文章來源:http://hi.baidu.com/zbzb/blog/item/ef6dae7724dae11cb151b9d4.html
    posted @ 2009-03-26 13:21 張永耀 閱讀(63) | 評論 (0)編輯 收藏

    閱讀全文
    類別:底層軟件 查看評論
    文章來源:http://hi.baidu.com/zbzb/blog/item/9013d0ca2ad45241f31fe763.html
    posted @ 2009-03-26 13:21 張永耀 閱讀(87) | 評論 (0)編輯 收藏

    僅列出標題
    共3頁: 上一頁 1 2 3 下一頁 
    主站蜘蛛池模板: 国产香蕉免费精品视频| 91视频免费观看| 毛片大全免费观看| 91嫩草亚洲精品| 国产成人免费午夜在线观看| 亚洲白嫩在线观看| 最新猫咪www免费人成| 亚洲精品中文字幕无码A片老| 在线观看免费成人| 美女无遮挡免费视频网站| 亚洲成AV人网址| 免费a级毛片无码a∨免费软件| 亚洲妇熟XXXX妇色黄| 久久99国产综合精品免费| 亚洲国产人成在线观看| 女人让男人免费桶爽30分钟| 美女露100%胸无遮挡免费观看 | 国产一级a毛一级a看免费人娇| 亚洲精品字幕在线观看| 在线人成精品免费视频| 亚洲日日做天天做日日谢| 国产精品国产自线拍免费软件| 亚洲阿v天堂在线2017免费| 亚洲AV无码欧洲AV无码网站| 4399好看日本在线电影免费| 鲁死你资源站亚洲av| 亚洲人成网77777色在线播放| 91热成人精品国产免费| 亚洲AV无码成人精品区日韩| 亚洲中文字幕日产乱码高清app| 亚洲 国产 图片| 国产精品小视频免费无限app| 精品亚洲A∨无码一区二区三区| 成年人在线免费观看| 成人一区二区免费视频| 亚洲成年人免费网站| 亚洲精品无码av天堂| 131美女爱做免费毛片| 国产亚洲午夜精品| 亚洲精品视频免费在线观看| 免费大黄网站在线看|