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

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

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

    隨筆-61  評論-13  文章-19  trackbacks-0
      2006年3月23日
         摘要:   閱讀全文
    posted @ 2010-02-04 15:30 xnabx 閱讀(1613) | 評論 (1)編輯 收藏
         摘要:   閱讀全文
    posted @ 2010-01-25 11:10 xnabx 閱讀(1029) | 評論 (1)編輯 收藏
         摘要:   閱讀全文
    posted @ 2010-01-21 09:52 xnabx 閱讀(1724) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2010-01-15 10:10 xnabx 閱讀(1407) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2010-01-15 09:57 xnabx 閱讀(336) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2009-12-04 11:45 xnabx 閱讀(605) | 評論 (3)編輯 收藏
         摘要:   閱讀全文
    posted @ 2009-12-03 15:26 xnabx 閱讀(312) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2009-12-01 16:02 xnabx 閱讀(186) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2009-12-01 11:05 xnabx 閱讀(321) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2009-11-10 09:05 xnabx 閱讀(759) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2009-03-18 14:06 xnabx 閱讀(149) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2008-10-29 16:34 xnabx 閱讀(112) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2008-07-30 15:18 xnabx 閱讀(239) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2008-07-23 11:20 xnabx 閱讀(387) | 評論 (0)編輯 收藏
    出處:http://m.tkk7.com/xmatthew/archive/2008/04/14/192450.html
    (轉)設計一個Tomcat訪問日志分析工具
    常使用web服務器的朋友大都了解,一般的web server有兩部分日志:
        一是運行中的日志,它主要記錄運行的一些信息,尤其是一些異常錯誤日志信息
        二是訪問日志信息,它記錄的訪問的時間,IP,訪問的資料等相關信息。
       
    現在我來和大家介紹一下利用tomcat產生的訪問日志數據,我們能做哪些有效的分析數據?

    首先是配置tomcat訪問日志數據,默認情況下訪問日志沒有打開,配置的方式如下:
        編輯 ${catalina}/conf/server.xml文件.注:${catalina}是tomcat的安裝目錄
        把以下的注釋(<!-- -->)去掉即可。
                <!--
            <Valve className="org.apache.catalina.valves.AccessLogValve"
                     directory="logs"  prefix="localhost_access_log." suffix=".txt"
                     pattern="common" resolveHosts="false"/>
            -->
        其中 directory是產生的目錄 tomcat安裝${catalina}作為當前目錄
        pattern表示日志生產的格式,common是tomcat提供的一個標準設置格式。其具體的表達式為 %h %l %u %t "%r" %s %b
        但本人建議采用以下具體的配置,因為標準配置有一些重要的日志數據無法生。
            %h %l %u %t "%r" %s %b %T 
    具體的日志產生樣式說明如下(從官方文檔中摘錄):
        * %a - Remote IP address
        * %A - Local IP address
        * %b - Bytes sent, excluding HTTP headers, or '-' if zero
        * %B - Bytes sent, excluding HTTP headers
        * %h - Remote host name (or IP address if resolveHosts is false)
        * %H - Request protocol
        * %l - Remote logical username from identd (always returns '-')
        * %m - Request method (GET, POST, etc.)
        * %p - Local port on which this request was received
        * %q - Query string (prepended with a '?' if it exists)
        * %r - First line of the request (method and request URI)
        * %s - HTTP status code of the response
        * %S - User session ID
        * %t - Date and time, in Common Log Format
        * %u - Remote user that was authenticated (if any), else '-'
        * %U - Requested URL path
        * %v - Local server name
        * %D - Time taken to process the request, in millis
        * %T - Time taken to process the request, in seconds

    There is also support to write information from the cookie, incoming header, the Session or something else in the ServletRequest. It is modeled after the apache syntax:

        * %{xxx}i for incoming headers
        * %{xxx}c for a specific cookie
        * %{xxx}r xxx is an attribute in the ServletRequest
        * %{xxx}s xxx is an attribute in the HttpSession


    現在我們回頭再來看一下下面這個配置 %h %l %u %t "%r" %s %b %T 生產的訪問日志數據,我們可以做哪些事?
    先看一下,我們能得到的數據有:
        * %h 訪問的用戶IP地址
        * %l 訪問邏輯用戶名,通常返回'-'
        * %u 訪問驗證用戶名,通常返回'-'
        * %t 訪問日時
        * %r 訪問的方式(post或者是get),訪問的資源和使用的http協議版本
        * %s 訪問返回的http狀態
        * %b 訪問資源返回的流量
        * %T 訪問所使用的時間
       
    有了這些數據,我們可以根據時間段做以下的分析處理(圖片使用jfreechart工具動態生成):
      * 獨立IP數統計
      * 訪問請求數統計
      * 訪問資料文件數統計
      * 訪問流量統計
      * 訪問處理響應時間統計
      * 統計所有404錯誤頁面
      * 統計所有500錯誤的頁面
      * 統計訪問最頻繁頁面
      * 統計訪問處理時間最久頁面
      * 統計并發訪問頻率最高的頁面



























    分析工具包括兩大部分,一個是后臺解釋程序,每天執行一次對后臺日志數據進行解析后保存到數據庫中。
    第二個是顯示程序,從數據庫中查詢數據并生成相應的圖表信息。
    posted @ 2008-04-15 12:06 xnabx 閱讀(560) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2008-04-09 08:50 xnabx 閱讀(36) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2008-03-19 13:00 xnabx 閱讀(187) | 評論 (0)編輯 收藏

    如果你覺得你的Eclipse在啟動的時候很慢(比如說超過20秒鐘),也許你要調整一下你的Eclipse啟動參數了,以下是一些``小貼士'':

    1. 檢查啟動Eclipse的JVM設置。 在Help\About Eclipse SDK\Configuration Detail里面,你可以看到啟動Eclipse的JVM。 這個JVM和你在Eclipse中設置的Installed JDK是兩回事情。 如果啟動Eclipse的JVM還是JDK 1.4的話,那最好改為JDK 5,因為JDK 5的性能比1.4更好。

    C:\eclipse\eclipse.exe -vm "C:\Program Files\Java\jdk1.5.0_08\ bin\javaw.exe"

    2. 檢查Eclipse所使用的heap的大小。 在C:\eclipse目錄下有一個配置文件eclipse.ini,其中配置了Eclipse啟動的默認heap大小

    -vmargs
    -Xms40M
    -Xmx256M

    所以你可以把默認值改為:

    -vmargs
    -Xms256M
    -Xmx512M

    當然,也可以這樣做,把堆的大小改為256 - 512。

    C:\eclipse\eclipse.exe -vm "C:\Program Files\Java\jdk1.5.0_08\ bin\javaw.exe" -vmargs -Xms256M -Xmx512M

    3. 其他的啟動參數。 如果你有一個雙核的CPU,也許可以嘗試這個參數:

    -XX:+UseParallelGC

    讓GC可以更快的執行。(只是JDK 5里對GC新增加的參數)

    posted @ 2007-12-25 10:55 xnabx 閱讀(487) | 評論 (0)編輯 收藏
     

    Java對多線程的支持與同步機制深受大家的喜愛,似乎看起來使用了synchronized關鍵字就可以輕松地解決多線程共享數據同步問題。到底如何?――還得對synchronized關鍵字的作用進行深入了解才可定論。

    總的說來,synchronized關鍵字可以作為函數的修飾符,也可作為函數內的語句,也就是平時說的同步方法和同步語句塊。如果再細的分類,synchronized可作用于instance變量、object reference(對象引用)、static函數和class literals(類名稱字面常量)身上。

    在進一步闡述之前,我們需要明確幾點:

    A.無論synchronized關鍵字加在方法上還是對象上,它取得的鎖都是對象,而不是把一段代碼或函數當作鎖――而且同步方法很可能還會被其他線程的對象訪問。

    B.每個對象只有一個鎖(lock)與之相關聯。

    C.實現同步是要很大的系統開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制。

    接著來討論synchronized用到不同地方對代碼產生的影響:

    假設P1、P2是同一個類的不同對象,這個類中定義了以下幾種情況的同步塊或同步方法,P1、P2就都可以調用它們。

    1. synchronized當作函數修飾符時,示例代碼如下:

    Public synchronized void methodAAA()

    {

    //….

    }

    這也就是同步方法,那這時synchronized鎖定的是哪個對象呢?它鎖定的是調用這個同步方法對象。也就是說,當一個對象P1在不同的線程中執行這個同步方法時,它們之間會形成互斥,達到同步的效果。但是這個對象所屬的Class所產生的另一對象P2卻可以任意調用這個被加了synchronized關鍵字的方法。

    上邊的示例代碼等同于如下代碼:

    public void methodAAA()

    {

    synchronized (this)      // (1)

    {

           //…..

    }

    }

     (1)處的this指的是什么呢?它指的就是調用這個方法的對象,如P1??梢娡椒椒▽嵸|是將synchronized作用于object reference。――那個拿到了P1對象鎖的線程,才可以調用P1的同步方法,而對P2而言,P1這個鎖與它毫不相干,程序也可能在這種情形下擺脫同步機制的控制,造成數據混亂:(

    2.同步塊,示例代碼如下:

               public void method3(SomeObject so)

                  {

                         synchronized(so)

    {

           //…..

    }

    }

    這時,鎖就是so這個對象,誰拿到這個鎖誰就可以運行它所控制的那段代碼。當有一個明確的對象作為鎖時,就可以這樣寫程序,但當沒有明確的對象作為鎖,只是想讓一段代碼同步時,可以創建一個特殊的instance變量(它得是一個對象)來充當鎖:

    class Foo implements Runnable

    {

           private byte[] lock = new byte[0]; // 特殊的instance變量

        Public void methodA()

    {

           synchronized(lock) { //… }

    }

    //…..

    }

    注:零長度的byte數組對象創建起來將比任何對象都經濟――查看編譯后的字節碼:生成零長度的byte[]對象只需3條操作碼,而Object lock = new Object()則需要7行操作碼。

    3.將synchronized作用于static 函數,示例代碼如下:

          Class Foo

    {

    public synchronized static void methodAAA()   // 同步的static 函數

    {

    //….

    }

    public void methodBBB()

    {

           synchronized(Foo.class)   // class literal(類名稱字面常量)

    }

           }

       代碼中的methodBBB()方法是把class literal作為鎖的情況,它和同步的static函數產生的效果是一樣的,取得的鎖很特別,是當前調用這個方法的對象所屬的類(Class,而不再是由這個Class產生的某個具體對象了)。

    記得在《Effective Java》一書中看到過將 Foo.class P1.getClass()用于作同步鎖還不一樣,不能用P1.getClass()來達到鎖這個Class的目的。P1指的是由Foo類產生的對象。

    可以推斷:如果一個類中定義了一個synchronizedstatic函數A,也定義了一個synchronized instance函數B,那么這個類的同一對象Obj在多線程中分別訪問AB兩個方法時,不會構成同步,因為它們的鎖都不一樣。A方法的鎖是Obj這個對象,而B的鎖是Obj所屬的那個Class。

    小結如下:

    搞清楚synchronized鎖定的是哪個對象,就能幫助我們設計更安全的多線程程序。

     

    還有一些技巧可以讓我們對共享資源的同步訪問更加安全:

    1. 定義private instance變量+它的 get方法,而不要定義public/protectedinstance變量。如果將變量定義為public,對象在外界可以繞過同步方法的控制而直接取得它,并改動它。這也是JavaBean的標準實現方式之一。

    2. 如果instance變量是一個對象,如數組或ArrayList什么的,那上述方法仍然不安全,因為當外界對象通過get方法拿到這個instance對象的引用后,又將其指向另一個對象,那么這個private變量也就變了,豈不是很危險。這個時候就需要將get方法也加上synchronized同步,并且,只返回這個private對象的clone()――這樣,調用端得到的就是對象副本的引用了。


    posted @ 2007-10-11 14:19 xnabx 閱讀(265) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2007-07-29 09:17 xnabx 閱讀(388) | 評論 (0)編輯 收藏

    這幾個學習材料非常短小精悍,可清晰快捷的掌握以下幾個概念,方便更深入學習 

    XML tutorial:

    http://www.w3schools.com/xml/default.asp

     

    SOAP tutorial:

    http://www.w3schools.com/soap/default.asp

     

    WSDL tutorial:

    http://www.w3schools.com/wsdl/default.asp

     

    WEB Service tutorial:

    http://www.w3schools.com/webservices/default.asp

    posted @ 2007-07-13 09:00 xnabx 閱讀(175) | 評論 (0)編輯 收藏


    類-->對象-->實例

    人類是類
    某個人是對象
    你是實例
    實例本身也是對象。

    表現出來是這樣的
    String 類
    String str   str是對象
    String str = "abc";  "abc"是實例,也是對象.
    這樣也能解釋instance of object這種說法  str的實例是"abc"
    posted @ 2007-07-05 08:47 xnabx 閱讀(430) | 評論 (1)編輯 收藏
    1.?概述?

    本文主要包括以下幾個方面:編碼基本知識,java,系統軟件,url,工具軟件等。?

    在下面的描述中,將以"中文"兩個字為例,經查表可以知道其GB2312編碼是"d6d0?cec4",Unicode編碼為"4e2d?6587",UTF編碼就是"e4b8ad?e69687"。注意,這兩個字沒有iso8859-1編碼,但可以用iso8859-1編碼來"表示"。?

    2.?編碼基本知識?

    最早的編碼是iso8859-1,和ascii編碼相似。但為了方便表示各種各樣的語言,逐漸出現了很多標準編碼,重要的有如下幾個。?

    2.1.?iso8859-1?

    屬于單字節編碼,最多能表示的字符范圍是0-255,應用于英文系列。比如,字母'a'的編碼為0x61=97。?

    很明顯,iso8859-1編碼表示的字符范圍很窄,無法表示中文字符。但是,由于是單字節編碼,和計算機最基礎的表示單位一致,所以很多時候,仍舊使用iso8859-1編碼來表示。而且在很多協議上,默認使用該編碼。比如,雖然"中文"兩個字不存在iso8859-1編碼,以gb2312編碼為例,應該是"d6d0?cec4"兩個字符,使用iso8859-1編碼的時候則將它拆開為4個字節來表示:"d6?d0?ce?c4"(事實上,在進行存儲的時候,也是以字節為單位處理的)。而如果是UTF編碼,則是6個字節"e4?b8?ad?e6?96?87"。很明顯,這種表示方法還需要以另一種編碼為基礎。?

    2.2.?GB2312/GBK?

    這就是漢子的國標碼,專門用來表示漢字,是雙字節編碼,而英文字母和iso8859-1一致(兼容iso8859-1編碼)。其中gbk編碼能夠用來同時表示繁體字和簡體字,而gb2312只能表示簡體字,gbk是兼容gb2312編碼的。?

    2.3.?unicode?

    這是最統一的編碼,可以用來表示所有語言的字符,而且是定長雙字節(也有四字節的)編碼,包括英文字母在內。所以可以說它是不兼容iso8859-1編碼的,也不兼容任何編碼。不過,相對于iso8859-1編碼來說,uniocode編碼只是在前面增加了一個0字節,比如字母'a'為"00?61"。?

    需要說明的是,定長編碼便于計算機處理(注意GB2312/GBK不是定長編碼),而unicode又可以用來表示所有字符,所以在很多軟件內部是使用unicode編碼來處理的,比如java。?

    2.4.?UTF?

    考慮到unicode編碼不兼容iso8859-1編碼,而且容易占用更多的空間:因為對于英文字母,unicode也需要兩個字節來表示。所以unicode不便于傳輸和存儲。因此而產生了utf編碼,utf編碼兼容iso8859-1編碼,同時也可以用來表示所有語言的字符,不過,utf編碼是不定長編碼,每一個字符的長度從1-6個字節不等。另外,utf編碼自帶簡單的校驗功能。一般來講,英文字母都是用一個字節表示,而漢字使用三個字節。?

    注意,雖然說utf是為了使用更少的空間而使用的,但那只是相對于unicode編碼來說,如果已經知道是漢字,則使用GB2312/GBK無疑是最節省的。不過另一方面,值得說明的是,雖然utf編碼對漢字使用3個字節,但即使對于漢字網頁,utf編碼也會比unicode編碼節省,因為網頁中包含了很多的英文字符。?

    3.?java對字符的處理?

    在java應用軟件中,會有多處涉及到字符集編碼,有些地方需要進行正確的設置,有些地方需要進行一定程度的處理。?

    3.1.?getBytes(charset)?

    這是java字符串處理的一個標準函數,其作用是將字符串所表示的字符按照charset編碼,并以字節方式表示。注意字符串在java內存中總是按unicode編碼存儲的。比如"中文",正常情況下(即沒有錯誤的時候)存儲為"4e2d?6587",如果charset為"gbk",則被編碼為"d6d0?cec4",然后返回字節"d6?d0?ce?c4"。如果charset為"utf8"則最后是"e4?b8?ad?e6?96?87"。如果是"iso8859-1",則由于無法編碼,最后返回?"3f?3f"(兩個問號)。?

    3.2.?new?String(charset)?

    這是java字符串處理的另一個標準函數,和上一個函數的作用相反,將字節數組按照charset編碼進行組合識別,最后轉換為unicode存儲。參考上述getBytes的例子,"gbk"?和"utf8"都可以得出正確的結果"4e2d?6587",但iso8859-1最后變成了"003f?003f"(兩個問號)。?

    因為utf8可以用來表示/編碼所有字符,所以new?String(?str.getBytes(?"utf8"?),?"utf8"?)?===?str,即完全可逆。?

    3.3.?setCharacterEncoding()?

    該函數用來設置http請求或者相應的編碼。?

    對于request,是指提交內容的編碼,指定后可以通過getParameter()則直接獲得正確的字符串,如果不指定,則默認使用iso8859-1編碼,需要進一步處理。參見下述"表單輸入"。值得注意的是在執行setCharacterEncoding()之前,不能執行任何getParameter()。java?doc上說明:This?method?must?be?called?prior?to?reading?request?parameters?or?reading?input?using?getReader()。而且,該指定只對POST方法有效,對GET方法無效。分析原因,應該是在執行第一個getParameter()的時候,java將會按照編碼分析所有的提交內容,而后續的getParameter()不再進行分析,所以setCharacterEncoding()無效。而對于GET方法提交表單是,提交的內容在URL中,一開始就已經按照編碼分析所有的提交內容,setCharacterEncoding()自然就無效。?

    對于response,則是指定輸出內容的編碼,同時,該設置會傳遞給瀏覽器,告訴瀏覽器輸出內容所采用的編碼。?

    3.4.?處理過程?

    下面分析兩個有代表性的例子,說明java對編碼有關問題的處理方法。?

    3.4.1.?表單輸入?

    User?input??*(gbk:d6d0?cec4)??browser??*(gbk:d6d0?cec4)??web?server??iso8859-1(00d6?00d?000ce?00c4)??class,需要在class中進行處理:getbytes("iso8859-1")為d6?d0?ce?c4,new?String("gbk")為d6d0?cec4,內存中以unicode編碼則為4e2d?6587。?

    l?用戶輸入的編碼方式和頁面指定的編碼有關,也和用戶的操作系統有關,所以是不確定的,上例以gbk為例。?

    l?從browser到web?server,可以在表單中指定提交內容時使用的字符集,否則會使用頁面指定的編碼。而如果在url中直接用?的方式輸入參數,則其編碼往往是操作系統本身的編碼,因為這時和頁面無關。上述仍舊以gbk編碼為例。?

    l?Web?server接收到的是字節流,默認時(getParameter)會以iso8859-1編碼處理之,結果是不正確的,所以需要進行處理。但如果預先設置了編碼(通過request.?setCharacterEncoding?()),則能夠直接獲取到正確的結果。?

    l?在頁面中指定編碼是個好習慣,否則可能失去控制,無法指定正確的編碼。?

    3.4.2.?文件編譯?

    假設文件是gbk編碼保存的,而編譯有兩種編碼選擇:gbk或者iso8859-1,前者是中文windows的默認編碼,后者是linux的默認編碼,當然也可以在編譯時指定編碼。?

    Jsp??*(gbk:d6d0?cec4)??java?file??*(gbk:d6d0?cec4)??compiler?read??uincode(gbk:?4e2d?6587;?iso8859-1:?00d6?00d?000ce?00c4)??compiler?write??utf(gbk:?e4b8ad?e69687;?iso8859-1:?*)??compiled?file??unicode(gbk:?4e2d?6587;?iso8859-1:?00d6?00d?000ce?00c4)??class。所以用gbk編碼保存,而用iso8859-1編譯的結果是不正確的。?

    class??unicode(4e2d?6587)??system.out?/?jsp.out??gbk(d6d0?cec4)??os?console?/?browser。?

    l?文件可以以多種編碼方式保存,中文windows下,默認為ansi/gbk。?

    l?編譯器讀取文件時,需要得到文件的編碼,如果未指定,則使用系統默認編碼。一般class文件,是以系統默認編碼保存的,所以編譯不會出問題,但對于jsp文件,如果在中文windows下編輯保存,而部署在英文linux下運行/編譯,則會出現問題。所以需要在jsp文件中用pageEncoding指定編碼。?

    l?Java編譯的時候會轉換成統一的unicode編碼處理,最后保存的時候再轉換為utf編碼。?

    l?當系統輸出字符的時候,會按指定編碼輸出,對于中文windows下,System.out將使用gbk編碼,而對于response(瀏覽器),則使用jsp文件頭指定的contentType,或者可以直接為response指定編碼。同時,會告訴browser網頁的編碼。如果未指定,則會使用iso8859-1編碼。對于中文,應該為browser指定輸出字符串的編碼。?

    l?browser顯示網頁的時候,首先使用response中指定的編碼(jsp文件頭指定的contentType最終也反映在response上),如果未指定,則會使用網頁中meta項指定中的contentType。?

    3.5.?幾處設置?

    對于web應用程序,和編碼有關的設置或者函數如下。?

    3.5.1.?jsp編譯?

    指定文件的存儲編碼,很明顯,該設置應該置于文件的開頭。例如:<%@page?pageEncoding="GBK"%>。另外,對于一般class文件,可以在編譯的時候指定編碼。?

    3.5.2.?jsp輸出?

    指定文件輸出到browser是使用的編碼,該設置也應該置于文件的開頭。例如:<%@?page?contentType="text/html;?charset=?GBK"?%>。該設置和response.setCharacterEncoding("GBK")等效。?

    3.5.3.?meta設置?

    指定網頁使用的編碼,該設置對靜態網頁尤其有作用。因為靜態網頁無法采用jsp的設置,而且也無法執行response.setCharacterEncoding()。例如:<META?http-equiv="Content-Type"?content="text/html;?charset=GBK"?/>?

    如果同時采用了jsp輸出和meta設置兩種編碼指定方式,則jsp指定的優先。因為jsp指定的直接體現在response中。?

    需要注意的是,apache有一個設置可以給無編碼指定的網頁指定編碼,該指定等同于jsp的編碼指定方式,所以會覆蓋靜態網頁中的meta指定。所以有人建議關閉該設置。?

    3.5.4.?form設置?

    當瀏覽器提交表單的時候,可以指定相應的編碼。例如:<form?accept-charset=?"gb2312">。一般不必不使用該設置,瀏覽器會直接使用網頁的編碼。?

    4.?系統軟件?

    下面討論幾個相關的系統軟件。?

    4.1.?mysql數據庫?

    很明顯,要支持多語言,應該將數據庫的編碼設置成utf或者unicode,而utf更適合與存儲。但是,如果中文數據中包含的英文字母很少,其實unicode更為適合。?

    數據庫的編碼可以通過mysql的配置文件設置,例如default-character-set=utf8。還可以在數據庫鏈接URL中設置,例如:?useUnicode=true&characterEncoding=UTF-8。注意這兩者應該保持一致,在新的sql版本里,在數據庫鏈接URL里可以不進行設置,但也不能是錯誤的設置。?

    4.2.?apache?

    appache和編碼有關的配置在httpd.conf中,例如AddDefaultCharset?UTF-8。如前所述,該功能會將所有靜態頁面的編碼設置為UTF-8,最好關閉該功能。?

    另外,apache還有單獨的模塊來處理網頁響應頭,其中也可能對編碼進行設置。?

    4.3.?linux默認編碼?

    這里所說的linux默認編碼,是指運行時的環境變量。兩個重要的環境變量是LC_ALL和LANG,默認編碼會影響到java?URLEncode的行為,下面有描述。?

    建議都設置為"zh_CN.UTF-8"。?

    4.4.?其它?

    為了支持中文文件名,linux在加載磁盤時應該指定字符集,例如:mount?/dev/hda5?/mnt/hda5/?-t?ntfs?-o?iocharset=gb2312。?

    另外,如前所述,使用GET方法提交的信息不支持request.setCharacterEncoding(),但可以通過tomcat的配置文件指定字符集,在tomcat的server.xml文件中,形如:<Connector?...?URIEncoding="GBK"/>。這種方法將統一設置所有請求,而不能針對具體頁面進行設置,也不一定和browser使用的編碼相同,所以有時候并不是所期望的。?

    5.?URL地址?

    URL地址中含有中文字符是很麻煩的,前面描述過使用GET方法提交表單的情況,使用GET方法時,參數就是包含在URL中。?

    5.1.?URL編碼?

    對于URL中的一些特殊字符,瀏覽器會自動進行編碼。這些字符除了"/?&"等外,還包括unicode字符,比如漢子。這時的編碼比較特殊。?

    IE有一個選項"總是使用UTF-8發送URL",當該選項有效時,IE將會對特殊字符進行UTF-8編碼,同時進行URL編碼。如果改選項無效,則使用默認編碼"GBK",并且不進行URL編碼。但是,對于URL后面的參數,則總是不進行編碼,相當于UTF-8選項無效。比如"中文.html?a=中文",當UTF-8選項有效時,將發送鏈接"%e4%b8%ad%e6%96%87.html?a=\x4e\x2d\x65\x87";而UTF-8選項無效時,將發送鏈接"\x4e\x2d\x65\x87.html?a=\x4e\x2d\x65\x87"。注意后者前面的"中文"兩個字只有4個字節,而前者卻有18個字節,這主要時URL編碼的原因。?

    當web?server(tomcat)接收到該鏈接時,將會進行URL解碼,即去掉"%",同時按照ISO8859-1編碼(上面已經描述,可以使用URLEncoding來設置成其它編碼)識別。上述例子的結果分別是"\ue4\ub8\uad\ue6\u96\u87.html?a=\u4e\u2d\u65\u87"和"\u4e\u2d\u65\u87.html?a=\u4e\u2d\u65\u87",注意前者前面的"中文"兩個字恢復成了6個字符。這里用"\u",表示是unicode。?

    所以,由于客戶端設置的不同,相同的鏈接,在服務器上得到了不同結果。這個問題不少人都遇到,卻沒有很好的解決辦法。所以有的網站會建議用戶嘗試關閉UTF-8選項。不過,下面會描述一個更好的處理辦法。?

    5.2.?rewrite?

    熟悉的人都知道,apache有一個功能強大的rewrite模塊,這里不描述其功能。需要說明的是該模塊會自動將URL解碼(去除%),即完成上述web?server(tomcat)的部分功能。有相關文檔介紹說可以使用[NE]參數來關閉該功能,但我試驗并未成功,可能是因為版本(我使用的是apache?2.0.54)問題。另外,當參數中含有"?&?"等符號的時候,該功能將導致系統得不到正常結果。?

    rewrite本身似乎完全是采用字節處理的方式,而不考慮字符串的編碼,所以不會帶來編碼問題。?

    5.3.?URLEncode.encode()?

    這是Java本身提供對的URL編碼函數,完成的工作和上述UTF-8選項有效時瀏覽器所做的工作相似。值得說明的是,java已經不贊成不指定編碼來使用該方法(deprecated)。應該在使用的時候增加編碼指定。?

    當不指定編碼的時候,該方法使用系統默認編碼,這會導致軟件運行結果得不確定。比如對于"中文",當系統默認編碼為"gb2312"時,結果是"%4e%2d%65%87",而默認編碼為"UTF-8",結果卻是"%e4%b8%ad%e6%96%87",后續程序將難以處理。另外,這兒說的系統默認編碼是由運行tomcat時的環境變量LC_ALL和LANG等決定的,曾經出現過tomcat重啟后就出現亂碼的問題,最后才郁悶的發現是因為修改修改了這兩個環境變量。?

    建議統一指定為"UTF-8"編碼,可能需要修改相應的程序。?

    5.4.?一個解決方案?

    上面說起過,因為瀏覽器設置的不同,對于同一個鏈接,web?server收到的是不同內容,而軟件系統有無法知道這中間的區別,所以這一協議目前還存在缺陷。?

    針對具體問題,不應該僥幸認為所有客戶的IE設置都是UTF-8有效的,也不應該粗暴的建議用戶修改IE設置,要知道,用戶不可能去記住每一個web?server的設置。所以,接下來的解決辦法就只能是讓自己的程序多一點智能:根據內容來分析編碼是否UTF-8。?

    比較幸運的是UTF-8編碼相當有規律,所以可以通過分析傳輸過來的鏈接內容,來判斷是否是正確的UTF-8字符,如果是,則以UTF-8處理之,如果不是,則使用客戶默認編碼(比如"GBK"),下面是一個判斷是否UTF-8的例子,如果你了解相應規律,就容易理解。?

    public?static?boolean?isValidUtf8(byte[]?b,int?aMaxCount){?

    ???????int?lLen=b.length,lCharCount=0;?

    ???????for(int?i=0;i<lLen?&&?lCharCount<aMaxCount;++lCharCount){?

    ??????????????byte?lByte=b[i++];//to?fast?operation,?++?now,?ready?for?the?following?for(;;)?

    ??????????????if(lByte>=0)?continue;//>=0?is?normal?ascii?

    ??????????????if(lByte<(byte)0xc0?||?lByte>(byte)0xfd)?return?false;?

    ??????????????int?lCount=lByte>(byte)0xfc?5:lByte>(byte)0xf8?4?

    ?????????????????????:lByte>(byte)0xf0?3:lByte>(byte)0xe0?2:1;?

    ??????????????if(i+lCount>lLen)?return?false;?

    ??????????????for(int?j=0;j<lCount;++j,++i)?if(b[i]>=(byte)0xc0)?return?false;?

    ???????}?

    ???????return?true;?

    }?

    相應地,一個使用上述方法的例子如下:?

    public?static?String?getUrlParam(String?aStr,String?aDefaultCharset)?

    throws?UnsupportedEncodingException{?

    ???????if(aStr==null)?return?null;?

    ???????byte[]?lBytes=aStr.getBytes("ISO-8859-1");?

    ???????return?new?String(lBytes,StringUtil.isValidUtf8(lBytes)?"utf8":aDefaultCharset);?

    }?

    不過,該方法也存在缺陷,如下兩方面:?

    l?沒有包括對用戶默認編碼的識別,這可以根據請求信息的語言來判斷,但不一定正確,因為我們有時候也會輸入一些韓文,或者其他文字。?

    l?可能會錯誤判斷UTF-8字符,一個例子是"學習"兩個字,其GBK編碼是"?\xd1\xa7\xcf\xb0",如果使用上述isValidUtf8方法判斷,將返回true。可以考慮使用更嚴格的判斷方法,不過估計效果不大。?

    有一個例子可以證明google也遇到了上述問題,而且也采用了和上述相似的處理方法,比如,如果在地址欄中輸入"http://www.google.com/search?hl=zh-CN&newwindow=1&q=學習",google將無法正確識別,而其他漢字一般能夠正常識別。?

    最后,應該補充說明一下,如果不使用rewrite規則,或者通過表單提交數據,其實并不一定會遇到上述問題,因為這時可以在提交數據時指定希望的編碼。另外,中文文件名確實會帶來問題,應該謹慎使用。?

    6.?其它?

    下面描述一些和編碼有關的其他問題。?

    6.1.?SecureCRT?

    除了瀏覽器和控制臺與編碼有關外,一些客戶端也很有關系。比如在使用SecureCRT連接linux時,應該讓SecureCRT的顯示編碼(不同的session,可以有不同的編碼設置)和linux的編碼環境變量保持一致。否則看到的一些幫助信息,就可能是亂碼。?

    另外,mysql有自己的編碼設置,也應該保持和SecureCRT的顯示編碼一致。否則通過SecureCRT執行sql語句的時候,可能無法處理中文字符,查詢結果也會出現亂碼。?

    對于Utf-8文件,很多編輯器(比如記事本)會在文件開頭增加三個不可見的標志字節,如果作為mysql的輸入文件,則必須要去掉這三個字符。(用linux的vi保存可以去掉這三個字符)。一個有趣的現象是,在中文windows下,創建一個新txt文件,用記事本打開,輸入"連通"兩個字,保存,再打開,你會發現兩個字沒了,只留下一個小黑點。?

    6.2.?過濾器?

    如果需要統一設置編碼,則通過filter進行設置是個不錯的選擇。在filter?class中,可以統一為需要的請求或者回應設置編碼。參加上述setCharacterEncoding()。這個類apache已經給出了可以直接使用的例子SetCharacterEncodingFilter。?

    6.3.?POST和GET?

    很明顯,以POST提交信息時,URL有更好的可讀性,而且可以方便的使用setCharacterEncoding()來處理字符集問題。但GET方法形成的URL能夠更容易表達網頁的實際內容,也能夠用于收藏。?

    從統一的角度考慮問題,建議采用GET方法,這要求在程序中獲得參數是進行特殊處理,而無法使用setCharacterEncoding()的便利,如果不考慮rewrite,就不存在IE的UTF-8問題,可以考慮通過設置URIEncoding來方便獲取URL中的參數。?

    6.4.?簡繁體編碼轉換?

    GBK同時包含簡體和繁體編碼,也就是說同一個字,由于編碼不同,在GBK編碼下屬于兩個字。有時候,為了正確取得完整的結果,應該將繁體和簡體進行統一。可以考慮將UTF、GBK中的所有繁體字,轉換為相應的簡體字,BIG5編碼的數據,也應該轉化成相應的簡體字。當然,仍舊以UTF編碼存儲。?

    例如,對于"語言??言",用UTF表示為"\xE8\xAF\xAD\xE8\xA8\x80?\xE8\xAA\x9E\xE8\xA8\x80",進行簡繁體編碼轉換后應該是兩個相同的?"\xE8\xAF\xAD\xE8\xA8\x80>"。?
    ?

    posted @ 2006-08-30 17:51 xnabx 閱讀(176) | 評論 (0)編輯 收藏
    URL
    http://sz.eeju.com/show_rent_99461.htm

    http://sz.eeju.com/show_rent_98823.htm

    http://sz.eeju.com/show_rent_96082.htm

    http://sz.eeju.com/show_rent_99193.htm

    http://sz.eeju.com/show_rent_99461.htm

    http://sz.eeju.com/show_rent_99181.htm

    http://rent.sz.soufun.com/cz/CZ_MLS_17845812.htm

    http://rent.sz.soufun.com/cz/CZ_MLS_17940110.htm

    http://rent.sz.soufun.com/cz/CZ_MLS_17852140.htm?***
    posted @ 2006-03-28 15:22 xnabx 閱讀(164) | 評論 (0)編輯 收藏

    插入排序:

    package org.rut.util.algorithm.support;

    import org.rut.util.algorithm.SortUtil;
    /**
    ?* @author treeroot
    ?* @since 2006-2-2
    ?* @version 1.0
    ?*/
    public class InsertSort implements SortUtil.Sort{

    ??? /* (non-Javadoc)
    ???? * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
    ???? */
    ??? public void sort(int[] data) {
    ??????? int temp;
    ??????? for(int i=1;i<data.length;i++){
    ??????????? for(int j=i;(j>0)&&(data[j]<data[j-1]);j--){
    ??????????????? SortUtil.swap(data,j,j-1);
    ??????????? }
    ??????? }???????
    ??? }

    }
    冒泡排序:

    package org.rut.util.algorithm.support;

    import org.rut.util.algorithm.SortUtil;

    /**
    ?* @author treeroot
    ?* @since 2006-2-2
    ?* @version 1.0
    ?*/
    public class BubbleSort implements SortUtil.Sort{

    ??? /* (non-Javadoc)
    ???? * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
    ???? */
    ??? public void sort(int[] data) {
    ??????? int temp;
    ??????? for(int i=0;i<data.length;i++){
    ??????????? for(int j=data.length-1;j>i;j--){
    ??????????????? if(data[j]<data[j-1]){
    ??????????????????? SortUtil.swap(data,j,j-1);
    ??????????????? }
    ??????????? }
    ??????? }
    ??? }

    }

    選擇排序:

    package org.rut.util.algorithm.support;

    import org.rut.util.algorithm.SortUtil;

    /**
    ?* @author treeroot
    ?* @since 2006-2-2
    ?* @version 1.0
    ?*/
    public class SelectionSort implements SortUtil.Sort {

    ??? /*
    ???? * (non-Javadoc)
    ???? *
    ???? * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
    ???? */
    ??? public void sort(int[] data) {
    ??????? int temp;
    ??????? for (int i = 0; i < data.length; i++) {
    ??????????? int lowIndex = i;
    ??????????? for (int j = data.length - 1; j > i; j--) {
    ??????????????? if (data[j] < data[lowIndex]) {
    ??????????????????? lowIndex = j;
    ??????????????? }
    ??????????? }
    ??????????? SortUtil.swap(data,i,lowIndex);
    ??????? }
    ??? }

    }

    Shell排序:

    package org.rut.util.algorithm.support;

    import org.rut.util.algorithm.SortUtil;

    /**
    ?* @author treeroot
    ?* @since 2006-2-2
    ?* @version 1.0
    ?*/
    public class ShellSort implements SortUtil.Sort{

    ??? /* (non-Javadoc)
    ???? * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
    ???? */
    ??? public void sort(int[] data) {
    ??????? for(int i=data.length/2;i>2;i/=2){
    ??????????? for(int j=0;j<i;j++){
    ??????????????? insertSort(data,j,i);
    ??????????? }
    ??????? }
    ??????? insertSort(data,0,1);
    ??? }

    ??? /**
    ???? * @param data
    ???? * @param j
    ???? * @param i
    ???? */
    ??? private void insertSort(int[] data, int start, int inc) {
    ??????? int temp;
    ??????? for(int i=start+inc;i<data.length;i+=inc){
    ??????????? for(int j=i;(j>=inc)&&(data[j]<data[j-inc]);j-=inc){
    ??????????????? SortUtil.swap(data,j,j-inc);
    ??????????? }
    ??????? }
    ??? }

    }

    快速排序:

    package org.rut.util.algorithm.support;

    import org.rut.util.algorithm.SortUtil;

    /**
    ?* @author treeroot
    ?* @since 2006-2-2
    ?* @version 1.0
    ?*/
    public class QuickSort implements SortUtil.Sort{

    ??? /* (non-Javadoc)
    ???? * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
    ???? */
    ??? public void sort(int[] data) {
    ??????? quickSort(data,0,data.length-1);???????
    ??? }
    ??? private void quickSort(int[] data,int i,int j){
    ??????? int pivotIndex=(i+j)/2;
    ??????? //swap
    ??????? SortUtil.swap(data,pivotIndex,j);
    ???????
    ??????? int k=partition(data,i-1,j,data[j]);
    ??????? SortUtil.swap(data,k,j);
    ??????? if((k-i)>1) quickSort(data,i,k-1);
    ??????? if((j-k)>1) quickSort(data,k+1,j);
    ???????
    ??? }
    ??? /**
    ???? * @param data
    ???? * @param i
    ???? * @param j
    ???? * @return
    ???? */
    ??? private int partition(int[] data, int l, int r,int pivot) {
    ??????? do{
    ?????????? while(data[++l]<pivot);
    ?????????? while((r!=0)&&data[--r]>pivot);
    ?????????? SortUtil.swap(data,l,r);
    ??????? }
    ??????? while(l<r);
    ??????? SortUtil.swap(data,l,r);???????
    ??????? return l;
    ??? }

    }
    改進后的快速排序:

    package org.rut.util.algorithm.support;

    import org.rut.util.algorithm.SortUtil;

    /**
    ?* @author treeroot
    ?* @since 2006-2-2
    ?* @version 1.0
    ?*/
    public class ImprovedQuickSort implements SortUtil.Sort {

    ??? private static int MAX_STACK_SIZE=4096;
    ??? private static int THRESHOLD=10;
    ??? /* (non-Javadoc)
    ???? * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
    ???? */
    ??? public void sort(int[] data) {
    ??????? int[] stack=new int[MAX_STACK_SIZE];
    ???????
    ??????? int top=-1;
    ??????? int pivot;
    ??????? int pivotIndex,l,r;
    ???????
    ??????? stack[++top]=0;
    ??????? stack[++top]=data.length-1;
    ???????
    ??????? while(top>0){
    ??????????? int j=stack[top--];
    ??????????? int i=stack[top--];
    ???????????
    ??????????? pivotIndex=(i+j)/2;
    ??????????? pivot=data[pivotIndex];
    ???????????
    ??????????? SortUtil.swap(data,pivotIndex,j);
    ???????????
    ??????????? //partition
    ??????????? l=i-1;
    ??????????? r=j;
    ??????????? do{
    ??????????????? while(data[++l]<pivot);
    ??????????????? while((r!=0)&&(data[--r]>pivot));
    ??????????????? SortUtil.swap(data,l,r);
    ??????????? }
    ??????????? while(l<r);
    ??????????? SortUtil.swap(data,l,r);
    ??????????? SortUtil.swap(data,l,j);
    ???????????
    ??????????? if((l-i)>THRESHOLD){
    ??????????????? stack[++top]=i;
    ??????????????? stack[++top]=l-1;
    ??????????? }
    ??????????? if((j-l)>THRESHOLD){
    ??????????????? stack[++top]=l+1;
    ??????????????? stack[++top]=j;
    ??????????? }
    ???????????
    ??????? }
    ??????? //new InsertSort().sort(data);
    ??????? insertSort(data);
    ??? }
    ??? /**
    ???? * @param data
    ???? */
    ??? private void insertSort(int[] data) {
    ??????? int temp;
    ??????? for(int i=1;i<data.length;i++){
    ??????????? for(int j=i;(j>0)&&(data[j]<data[j-1]);j--){
    ??????????????? SortUtil.swap(data,j,j-1);
    ??????????? }
    ??????? }??????
    ??? }

    }

    歸并排序:

    package org.rut.util.algorithm.support;

    import org.rut.util.algorithm.SortUtil;

    /**
    ?* @author treeroot
    ?* @since 2006-2-2
    ?* @version 1.0
    ?*/
    public class MergeSort implements SortUtil.Sort{

    ??? /* (non-Javadoc)
    ???? * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
    ???? */
    ??? public void sort(int[] data) {
    ??????? int[] temp=new int[data.length];
    ??????? mergeSort(data,temp,0,data.length-1);
    ??? }
    ???
    ??? private void mergeSort(int[] data,int[] temp,int l,int r){
    ??????? int mid=(l+r)/2;
    ??????? if(l==r) return ;
    ??????? mergeSort(data,temp,l,mid);
    ??????? mergeSort(data,temp,mid+1,r);
    ??????? for(int i=l;i<=r;i++){
    ??????????? temp[i]=data[i];
    ??????? }
    ??????? int i1=l;
    ??????? int i2=mid+1;
    ??????? for(int cur=l;cur<=r;cur++){
    ??????????? if(i1==mid+1)
    ??????????????? data[cur]=temp[i2++];
    ??????????? else if(i2>r)
    ??????????????? data[cur]=temp[i1++];
    ??????????? else if(temp[i1]<temp[i2])
    ??????????????? data[cur]=temp[i1++];
    ??????????? else
    ??????????????? data[cur]=temp[i2++];???????????
    ??????? }
    ??? }

    }

    改進后的歸并排序:

    package org.rut.util.algorithm.support;

    import org.rut.util.algorithm.SortUtil;

    /**
    ?* @author treeroot
    ?* @since 2006-2-2
    ?* @version 1.0
    ?*/
    public class ImprovedMergeSort implements SortUtil.Sort {

    ??? private static final int THRESHOLD = 10;

    ??? /*
    ???? * (non-Javadoc)
    ???? *
    ???? * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
    ???? */
    ??? public void sort(int[] data) {
    ??????? int[] temp=new int[data.length];
    ??????? mergeSort(data,temp,0,data.length-1);
    ??? }

    ??? private void mergeSort(int[] data, int[] temp, int l, int r) {
    ??????? int i, j, k;
    ??????? int mid = (l + r) / 2;
    ??????? if (l == r)
    ??????????? return;
    ??????? if ((mid - l) >= THRESHOLD)
    ??????????? mergeSort(data, temp, l, mid);
    ??????? else
    ??????????? insertSort(data, l, mid - l + 1);
    ??????? if ((r - mid) > THRESHOLD)
    ??????????? mergeSort(data, temp, mid + 1, r);
    ??????? else
    ??????????? insertSort(data, mid + 1, r - mid);

    ??????? for (i = l; i <= mid; i++) {
    ??????????? temp[i] = data[i];
    ??????? }
    ??????? for (j = 1; j <= r - mid; j++) {
    ??????????? temp[r - j + 1] = data[j + mid];
    ??????? }
    ??????? int a = temp[l];
    ??????? int b = temp[r];
    ??????? for (i = l, j = r, k = l; k <= r; k++) {
    ??????????? if (a < b) {
    ??????????????? data[k] = temp[i++];
    ??????????????? a = temp[i];
    ??????????? } else {
    ??????????????? data[k] = temp[j--];
    ??????????????? b = temp[j];
    ??????????? }
    ??????? }
    ??? }

    ??? /**
    ???? * @param data
    ???? * @param l
    ???? * @param i
    ???? */
    ??? private void insertSort(int[] data, int start, int len) {
    ??????? for(int i=start+1;i<start+len;i++){
    ??????????? for(int j=i;(j>start) && data[j]<data[j-1];j--){
    ??????????????? SortUtil.swap(data,j,j-1);
    ??????????? }
    ??????? }
    ??? }

    }
    堆排序:

    package org.rut.util.algorithm.support;

    import org.rut.util.algorithm.SortUtil;

    /**
    ?* @author treeroot
    ?* @since 2006-2-2
    ?* @version 1.0
    ?*/
    public class HeapSort implements SortUtil.Sort{

    ??? /* (non-Javadoc)
    ???? * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
    ???? */
    ??? public void sort(int[] data) {
    ??????? MaxHeap h=new MaxHeap();
    ??????? h.init(data);
    ??????? for(int i=0;i<data.length;i++)
    ??????????? h.remove();
    ??????? System.arraycopy(h.queue,1,data,0,data.length);
    ??? }


    ???? private static class MaxHeap{
    ????????
    ???????
    ??????? void init(int[] data){
    ??????????? this.queue=new int[data.length+1];
    ??????????? for(int i=0;i<data.length;i++){
    ??????????????? queue[++size]=data[i];
    ??????????????? fixUp(size);
    ??????????? }
    ??????? }
    ????????
    ??????? private int size=0;

    ??????? private int[] queue;
    ???????????????
    ??????? public int get() {
    ??????????? return queue[1];
    ??????? }

    ??????? public void remove() {
    ??????????? SortUtil.swap(queue,1,size--);
    ??????????? fixDown(1);
    ??????? }
    ??????? //fixdown
    ??????? private void fixDown(int k) {
    ??????????? int j;
    ??????????? while ((j = k << 1) <= size) {
    ??????????????? if (j < size && queue[j]<queue[j+1])
    ??????????????????? j++;
    ??????????????? if (queue[k]>queue[j]) //不用交換
    ??????????????????? break;
    ??????????????? SortUtil.swap(queue,j,k);
    ??????????????? k = j;
    ??????????? }
    ??????? }
    ??????? private void fixUp(int k) {
    ??????????? while (k > 1) {
    ??????????????? int j = k >> 1;
    ??????????????? if (queue[j]>queue[k])
    ??????????????????? break;
    ??????????????? SortUtil.swap(queue,j,k);
    ??????????????? k = j;
    ??????????? }
    ??????? }

    ??? }

    }

    ?

    SortUtil:

    package org.rut.util.algorithm;

    import org.rut.util.algorithm.support.BubbleSort;
    import org.rut.util.algorithm.support.HeapSort;
    import org.rut.util.algorithm.support.ImprovedMergeSort;
    import org.rut.util.algorithm.support.ImprovedQuickSort;
    import org.rut.util.algorithm.support.InsertSort;
    import org.rut.util.algorithm.support.MergeSort;
    import org.rut.util.algorithm.support.QuickSort;
    import org.rut.util.algorithm.support.SelectionSort;
    import org.rut.util.algorithm.support.ShellSort;

    /**
    ?* @author treeroot
    ?* @since 2006-2-2
    ?* @version 1.0
    ?*/
    public class SortUtil {
    ??? public final static int INSERT = 1;

    ??? public final static int BUBBLE = 2;

    ??? public final static int SELECTION = 3;

    ??? public final static int SHELL = 4;

    ??? public final static int QUICK = 5;

    ??? public final static int IMPROVED_QUICK = 6;

    ??? public final static int MERGE = 7;

    ??? public final static int IMPROVED_MERGE = 8;

    ??? public final static int HEAP = 9;

    ??? public static void sort(int[] data) {
    ??????? sort(data, IMPROVED_QUICK);
    ??? }
    ??? private static String[] name={
    ??????????? "insert","bubble","selection","shell","quick","improved_quick","merge","improved_merge","heap"
    ??? };
    ???
    ??? private static Sort[] impl=new Sort[]{
    ??????????? new InsertSort(),
    ??????????? new BubbleSort(),
    ??????????? new SelectionSort(),
    ??????????? new ShellSort(),
    ??????????? new QuickSort(),
    ??????????? new ImprovedQuickSort(),
    ??????????? new MergeSort(),
    ??????????? new ImprovedMergeSort(),
    ??????????? new HeapSort()
    ??? };

    ??? public static String toString(int algorithm){
    ??????? return name[algorithm-1];
    ??? }
    ???
    ??? public static void sort(int[] data, int algorithm) {
    ??????? impl[algorithm-1].sort(data);
    ??? }

    ??? public static interface Sort {
    ??????? public void sort(int[] data);
    ??? }

    ??? public static void swap(int[] data, int i, int j) {
    ??????? int temp = data[i];
    ??????? data[i] = data[j];
    ??????? data[j] = temp;
    ??? }
    }

    posted @ 2006-03-27 17:58 xnabx 閱讀(150) | 評論 (0)編輯 收藏
    Unicode解決方案
    Unicode:寬字節字符集(摘自windows核心編程)

    UnicodeAppleXerox公司于1988年建立的一個技術標準。1991年,成立了一個集團機構負責Unicode的開發和推廣應用。該集團由Apple、Compaq、IBM、Microsoft、Oracle、Silicon ? Graphics, ? Inc.Sybase、UnisysXerox等公司組成。該集團負責維護Unicode標準。
    Unicode
    提供了一種簡單而又一致的表示字符串的方法。Unicode字符串中的所有字符都是16位的(兩個字節)。它沒有專門的字節來指明下一個字節是屬于同一個字符的組成部分,還是一個新字符。這意味著你只需要對指針進行遞增或遞減,就可以遍歷字符串中的各個字符,不再需要調用CharNext之類的函數。由于Unicode用一個16位的值來表示每個字符,因此總共可以得到65000個字符,這樣,它就能夠對世界各國的書面文字中的所有字符進行編碼,遠遠超過了單字節字符集的256個字符的數目。




    我們面臨的基本問題是世界上的書寫語言不能簡單地用256個8位代碼表示。以前的解決方案包括代碼頁和DBCS已被證明是不能滿足需要的,而且也是笨拙的。那什么才是真正的解決方案呢?

    身為程序編寫者,我們經歷過這類問題。如果事情太多,用8位數值已經不能表示,那么我們就試更寬的值,例如16位值。而且這很有趣的,正是Unicode被制定的原因。與混亂的256個字符代碼映像,以及含有一些1字節代碼和一些2字節代碼的雙字節字符集不同,Unicode是統一的16位系統,這樣就允許表示65,536個字符。這對表示所有字符及世界上使用象形文字的語言,包括一系列的數學、符號和貨幣單位符號的集合來說是充裕的。

    明白Unicode和DBCS之間的區別很重要。Unicode使用(特別在C程序設計語言環境里)“寬字符集”。“Unicode中的每個字符都是16位寬而不是8位寬?!痹赨nicode中,沒有單單使用8位數值的意義存在。相比之下,在雙字節字符集中我們仍然處理8位數值。有些字節自身定義字符,而某些字節則顯示需要和另一個字節共同定義一個字符。

    處理DBCS字符串非常雜亂,但是處理Unicode文字則像處理有秩序的文字。您也許會高興地知道前128個Unicode字符(16位代碼從0x0000到0x007F)就是ASCII字符,而接下來的128個Unicode字符(代碼從0x0080到0x00FF)是ISO ? 8859-1對ASCII的擴展。Unicode中不同部分的字符都同樣基于現有的標準。這是為了便于轉換。希臘字母表使用從0x0370到0x03FF的代碼,斯拉夫語使用從0x0400到0x04FF的代碼,美國使用從0x0530到0x058F的代碼,希伯來語使用從0x0590到0x05FF的代碼。中國、日本和韓國的象形文字(總稱為CJK)占用了從0x3000到0x9FFF的代碼。

    Unicode的最大好處是這里只有一個字符集,沒有一點含糊。Unicode實際上是個人計算機行業中幾乎每個重要公司共同合作的結果,并且它與ISO ? 10646-1標準中的代碼是一一對應的。Unicode的重要參考文獻是《The ? Unicode ? Standard,Version ? 2.0》(Addison-Wesley出版社,1996年)。這是一本特別的書,它以其它文件少有的方式顯示了世界上書寫語言的豐富性和多樣性。此外,該書還提供了開發Unicode的基本原理和細節。

    Unicode有缺點嗎?當然有。Unicode字符串占用的內存是ASCII字符串的兩倍。(然而壓縮文件有助于極大地減少文件所占的磁盤空間。)但也許最糟的缺點是:人們相對來說還不習慣使用Unicode。身為程序編寫者,這就是我們的工作

    posted @ 2006-03-27 17:49 xnabx 閱讀(148) | 評論 (0)編輯 收藏

    插件下載地址:
    http://www.delphibbs.com/keylife/images/u88173/csdnkantie.rar
    下載后解壓到myIE的plugin目錄即可。

    例如我的解壓后的目錄:
    D:\programs\Maxthon\Plugin\csdnkantie\

    效果圖:

    http://blog.csdn.net/images/blog_csdn_net/pigo/36738/o_casdnkanite001.gif

    http://blog.csdn.net/images/blog_csdn_net/pigo/36738/o_casdnkanite001.gif

    posted @ 2006-03-27 17:20 xnabx 閱讀(122) | 評論 (0)編輯 收藏
    pop-ent.21cn.com
    @shareinfo.com.cn
    posted @ 2006-03-27 16:51 xnabx 閱讀(143) | 評論 (0)編輯 收藏

    在Connection上調用close方法會關閉Statement和ResultSet嗎?

    級聯的關閉這聽起來好像很有道理,而且在很多地方這樣做也是正確的,通常這樣寫
    Connection con = getConnection();//getConnection is your method
    PreparedStatement ps = con.prepareStatement(sql);
    ResultSet rs = ps.executeQuery();
    ……
    ///rs.close();
    ///ps.close();
    con.close();? // NO!
    這樣做的問題在于Connection是個接口,它的close實現可能是多種多樣的。在普通情況下,你用 DriverManager.getConnection()得到一個Connection實例,調用它的close方法會關閉Statement和 ResultSet。但是在很多時候,你需要使用數據庫連接池,在連接池中的得到的Connection上調用close方法的時候,Connection可能并沒有被釋放,而是回到了連接池中。它以后可能被其它代碼取出來用。如果沒有釋放Statement和ResultSet,那么在Connection上沒有關閉的Statement和ResultSet可能會越來越多,那么……
    相反,我看到過這樣的說法,有人把Connection關閉了,卻繼續使用ResultSet,認為這樣是可以的,引發了激烈的討論,到底是怎么回事就不用我多說了吧。

    所以我們必須很小心的釋放數據庫資源,下面的代碼片斷展示了這個過程

    Connection con = null;
    PreparedStatement ps = null;
    ResultSet rs = null;

    try {
    ??? con = getConnection();//getConnection is your method
    ??? ps = con.prepareStatement(sql);
    ??? rs = ps.executeQuery();
    ??? ///...........
    }
    catch (SQLException ex) {
    ??? ///錯誤處理
    }
    finally{
    ??? try {
    ??????? if(ps!=null)
    ??????????? ps.close();
    ??? }
    ??? catch (SQLException ex) {
    ??????? ///錯誤處理
    ??? }
    ??? try{
    ??????? if(con!=null)
    ??????????? con.close();
    ??? }
    ??? catch (SQLException ex) {
    ??????? ///錯誤處理
    ??? }
    }

    ?

    posted @ 2006-03-23 22:27 xnabx 閱讀(505) | 評論 (0)編輯 收藏

    1. Open:? Internet Options --> Content --> AutoComplete

    2. Click button: ?'Clear Forms' and 'Clear Passwords'

    posted @ 2006-03-23 22:07 xnabx 閱讀(344) | 評論 (0)編輯 收藏

    public class TranCharset {

    ??? private static final String PRE_FIX_UTF = "&#x";
    ??? private static final String POS_FIX_UTF = ";";

    ??? public TranCharset() {
    ??? }

    ??? /**
    ???? * Translate charset encoding to unicode
    ???? *
    ???? * @param sTemp charset encoding is gb2312
    ???? * @return charset encoding is unicode
    ???? */
    ??? public static String XmlFormalize(String sTemp) {
    ??????? StringBuffer sb = new StringBuffer();

    ??????? if (sTemp == null || sTemp.equals("")) {
    ??????????? return "";
    ??????? }
    ??????? String s = TranCharset.TranEncodeTOGB(sTemp);
    ??????? for (int i = 0; i < s.length(); i++) {
    ??????????? char cChar = s.charAt(i);
    ??????????? if (TranCharset.isGB2312(cChar)) {
    ??????????????? sb.append(PRE_FIX_UTF);
    ??????????????? sb.append(Integer.toHexString(cChar));
    ??????????????? sb.append(POS_FIX_UTF);
    ??????????? } else {
    ??????????????? switch ((int) cChar) {
    ??????????????????? case 32:
    ??????????????????????? sb.append("&#32;");
    ??????????????????????? break;
    ??????????????????? case 34:
    ??????????????????????? sb.append("&quot;");
    ??????????????????????? break;
    ??????????????????? case 38:
    ??????????????????????? sb.append("&amp;");
    ??????????????????????? break;
    ??????????????????? case 60:
    ??????????????????????? sb.append("&lt;");
    ??????????????????????? break;
    ??????????????????? case 62:
    ??????????????????????? sb.append("&gt;");
    ??????????????????????? break;
    ??????????????????? default:
    ??????????????????????? sb.append(cChar);
    ??????????????? }
    ??????????? }
    ??????? }
    ??????? return sb.toString();
    ??? }

    ??? /**
    ???? * 將字符串編碼格式轉成GB2312
    ???? *
    ???? * @param str
    ???? * @return
    ???? */
    ??? public static String TranEncodeTOGB(String str) {
    ??????? try {
    ??????????? String strEncode = TranCharset.getEncoding(str);
    ??????????? String temp = new String(str.getBytes(strEncode), "GB2312");
    ??????????? return temp;
    ??????? } catch (java.io.IOException ex) {

    ??????????? return null;
    ??????? }
    ??? }

    ??? /**
    ???? * 判斷輸入字符是否為gb2312的編碼格式
    ???? *
    ???? * @param c 輸入字符
    ???? * @return 如果是gb2312返回真,否則返回假
    ???? */
    ??? public static boolean isGB2312(char c) {
    ??????? Character ch = new Character(c);
    ??????? String sCh = ch.toString();
    ??????? try {
    ??????????? byte[] bb = sCh.getBytes("gb2312");
    ??????????? if (bb.length > 1) {
    ??????????????? return true;
    ??????????? }
    ??????? } catch (java.io.UnsupportedEncodingException ex) {
    ??????????? return false;
    ??????? }
    ??????? return false;
    ??? }

    ??? /**
    ???? * 判斷字符串的編碼
    ???? *
    ???? * @param str
    ???? * @return
    ???? */
    ??? public static String getEncoding(String str) {
    ??????? String encode = "GB2312";
    ??????? try {
    ??????????? if (str.equals(new String(str.getBytes(encode), encode))) {
    ??????????????? String s = encode;
    ??????????????? return s;
    ??????????? }
    ??????? } catch (Exception exception) {
    ??????? }
    ??????? encode = "ISO-8859-1";
    ??????? try {
    ??????????? if (str.equals(new String(str.getBytes(encode), encode))) {
    ??????????????? String s1 = encode;
    ??????????????? return s1;
    ??????????? }
    ??????? } catch (Exception exception1) {
    ??????? }
    ??????? encode = "UTF-8";
    ??????? try {
    ??????????? if (str.equals(new String(str.getBytes(encode), encode))) {
    ??????????????? String s2 = encode;
    ??????????????? return s2;
    ??????????? }
    ??????? } catch (Exception exception2) {
    ??????? }
    ??????? encode = "GBK";
    ??????? try {
    ??????????? if (str.equals(new String(str.getBytes(encode), encode))) {
    ??????????????? String s3 = encode;
    ??????????????? return s3;
    ??????????? }
    ??????? } catch (Exception exception3) {
    ??????? }
    ??????? encode = "BIG5";
    ??????? try {
    ??????????? if (str.equals(new String(str.getBytes(encode), encode))) {
    ??????????????? String s4 = encode;
    ??????????????? return s4;
    ??????????? }
    ??????? } catch (Exception exception3) {
    ??????? }
    ??????? return "";
    ??? }

    ??? public static void main(String args[]) {
    ??????? System.out.println(XmlFormalize("下載"));
    ??? }
    }

    posted @ 2006-03-23 09:16 xnabx 閱讀(150) | 評論 (0)編輯 收藏
    主站蜘蛛池模板: 亚洲乱码中文字幕综合 | 国产亚洲无线码一区二区| 国产一区二区三区免费观在线| 亚洲av中文无码乱人伦在线r▽| 91精品国产免费久久久久久青草| 久久精品亚洲日本波多野结衣 | 亚洲免费观看视频| 在线看片无码永久免费视频| 无遮挡a级毛片免费看| 久久精品国产亚洲AV无码娇色| 国产精品99久久免费| 久久这里只精品热免费99| 亚洲中文字幕乱码AV波多JI| 91麻豆国产自产在线观看亚洲 | 久久精品国产精品亚洲艾草网美妙| 免费A级毛片无码A∨免费| 免费精品国自产拍在线播放| 久久亚洲精品无码VA大香大香 | 亚洲中文字幕无码爆乳| 国产亚洲精品美女久久久 | 久久精品国产精品亚洲蜜月 | 亚洲大香伊人蕉在人依线| 亚洲av无码成人精品区| 久久久久久久91精品免费观看| 一级毛片a免费播放王色| 中文文字幕文字幕亚洲色| 亚洲人成图片小说网站| 日韩免费观看视频| 久久A级毛片免费观看| a级毛片免费高清视频| 亚洲av午夜国产精品无码中文字 | 亚洲人成色在线观看| 亚洲天堂中文字幕| 亚洲精品乱码久久久久久蜜桃| 91在线视频免费播放| 久久中文字幕免费视频| 春意影院午夜爽爽爽免费| 亚洲精品蜜夜内射| 亚洲欧洲日韩在线电影| 亚洲AV色香蕉一区二区| 亚洲综合区小说区激情区|