posts - 19, comments - 1, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          2006年9月28日

          正則表達式是煩瑣的,但是強大的,學會之后的應用會讓你除了提高效率外,會給你帶來絕對的成就感。只要認真去閱讀這些資料,加上應用的時候進行一定的參考,掌握正則表達式不是問題。

          索引

          1. 引子
          2. 正則表達式的歷史
          3. 正則表達式定義

          3.1 普通字符
          3.2 非打印字符
          3.3 特殊字符
          3.4 限定符
          3.5 定位符
          3.6 選擇
          3.7 后向引用

          4. 各種操作符的運算優先級
          5. 全部符號解釋
          6. 部分例子
          7. 正則表達式匹配規則

          7.1 基本模式匹配
          7.2 字符簇
          7.3 確定重復出現

          1. 引子
            目前,正則表達式已經在很多軟件中得到廣泛的應用,包括*nix(Linux, Unix等),HP等操作系統,PHP,C#,Java等開發環境,以及很多的應用軟件中,都可以看到正則表達式的影子。

            正則表達式的使用,可以通過簡單的辦法來實現強大的功能。為了簡單有效而又不失強大,造成了正則表達式代碼的難度較大,學習起來也不是很容易,所以需要付出一些努力才行,入門之后參照一定的參考,使用起來還是比較簡單有效的。

          例子: ^.+@.+\\..+$

            這樣的代碼曾經多次把我自己給嚇退過。可能很多人也是被這樣的代碼給嚇跑的吧。繼續閱讀本文將讓你也可以自由應用這樣的代碼。

            注意:這里的第7部分跟前面的內容看起來似乎有些重復,目的是把前面表格里的部分重新描述了一次,目的是讓這些內容更容易理解。

          2. 正則表達式的歷史
            正則表達式的“祖先”可以一直上溯至對人類神經系統如何工作的早期研究。Warren McCulloch 和 Walter Pitts 這兩位神經生理學家研究出一種數學方式來描述這些神經網絡。
            1956 年, 一位叫 Stephen Kleene 的數學家在 McCulloch 和 Pitts 早期工作的基礎上,發表了一篇標題為“神經網事件的表示法”的論文,引入了正則表達式的概念。正則表達式就是用來描述他稱為“正則集的代數”的表達式,因此采用“正則表達式”這個術語。

            隨后,發現可以將這一工作應用于使用 Ken Thompson 的計算搜索算法的一些早期研究,Ken Thompson 是 Unix 的主要發明人。正則表達式的第一個實用應用程序就是 Unix 中的 qed 編輯器。

            如他們所說,剩下的就是眾所周知的歷史了。從那時起直至現在正則表達式都是基于文本的編輯器和搜索工具中的一個重要部分。

           

          3. 正則表達式定義
            正則表達式(regular expression)描述了一種字符串匹配的模式,可以用來檢查一個串是否含有某種子串、將匹配的子串做替換或者從某個串中取出符合某個條件的子串等。

          列目錄時, dir *.txt或ls *.txt中的*.txt就不是一個正則表達式,因為這里*與正則式的*的含義是不同的。
            正則表達式是由普通字符(例如字符 a 到 z)以及特殊字符(稱為元字符)組成的文字模式。正則表達式作為一個模板,將某個字符模式與所搜索的字符串進行匹配。

          3.1 普通字符
            由所有那些未顯式指定為元字符的打印和非打印字符組成。這包括所有的大寫和小寫字母字符,所有數字,所有標點符號以及一些符號。

          3.2 非打印字符
          字符 含義
          \cx 匹配由x指明的控制字符。例如, \cM 匹配一個 Control-M 或回車符。x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個原義的 ‘c’ 字符。
          \f 匹配一個換頁符。等價于 \x0c 和 \cL。
          \n 匹配一個換行符。等價于 \x0a 和 \cJ。
          \r 匹配一個回車符。等價于 \x0d 和 \cM。
          \s 匹配任何空白字符,包括空格、制表符、換頁符等等。等價于 [ \f\n\r\t\v]。
          \S 匹配任何非空白字符。等價于 [^ \f\n\r\t\v]。
          \t 匹配一個制表符。等價于 \x09 和 \cI。
          \v 匹配一個垂直制表符。等價于 \x0b 和 \cK。

           
          3.3 特殊字符
            所謂特殊字符,就是一些有特殊含義的字符,如上面說的”*.txt”中的*,簡單的說就是表示任何字符串的意思。如果要查找文件名中有*的文件,則需要對*進行轉義,即在其前加一個\。ls \*.txt。正則表達式有以下特殊字符。
           

          特別字符 說明
          $ 匹配輸入字符串的結尾位置。如果設置了 RegExp 對象的 Multiline 屬性,則 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,請使用 \$。
          ( ) 標記一個子表達式的開始和結束位置。子表達式可以獲取供以后使用。要匹配這些字符,請使用 \( 和 \)。
          * 匹配前面的子表達式零次或多次。要匹配 * 字符,請使用 \*。
          + 匹配前面的子表達式一次或多次。要匹配 + 字符,請使用 \+。
          . 匹配除換行符 \n之外的任何單字符。要匹配 .,請使用 \。
          [ 標記一個中括號表達式的開始。要匹配 [,請使用 \[。
          ? 匹配前面的子表達式零次或一次,或指明一個非貪婪限定符。要匹配 ? 字符,請使用 \?。
          \ 將下一個字符標記為或特殊字符、或原義字符、或向后引用、或八進制轉義符。例如, ‘n’ 匹配字符 ‘n’。’\n’ 匹配換行符。序列 ‘\\’ 匹配 “\”,而 ‘\(’ 則匹配 “(”。
          ^ 匹配輸入字符串的開始位置,除非在方括號表達式中使用,此時它表示不接受該字符集合。要匹配 ^ 字符本身,請使用 \^。
          { 標記限定符表達式的開始。要匹配 {,請使用 \{。
          | 指明兩項之間的一個選擇。要匹配 |,請使用 \|。

            構造正則表達式的方法和創建數學表達式的方法一樣。也就是用多種元字符與操作符將小的表達式結合在一起來創建更大的表達式。正則表達式的組件可以是單個的字符、字符集合、字符范圍、字符間的選擇或者所有這些組件的任意組合。
           

          3.4 限定符
            限定符用來指定正則表達式的一個給定組件必須要出現多少次才能滿足匹配。有*或+或?或{n}或{n,}或{n,m}共6種。
          *、+和?限定符都是貪婪的,因為它們會盡可能多的匹配文字,只有在它們的后面加上一個?就可以實現非貪婪或最小匹配。
            正則表達式的限定符有:
            字符 描述
          * 匹配前面的子表達式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等價于{0,}。
          + 匹配前面的子表達式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等價于 {1,}。
          ? 匹配前面的子表達式零次或一次。例如,”do(es)?” 可以匹配 “do” 或 “does” 中的”do” 。? 等價于 {0,1}。
          {n} n 是一個非負整數。匹配確定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的兩個 o。
          {n,} n 是一個非負整數。至少匹配n 次。例如,’o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。’o{1,}’ 等價于 ‘o+’。’o{0,}’ 則等價于 ‘o*’。
          {n,m} m 和 n 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,”o{1,3}” 將匹配 “fooooood” 中的前三個 o。’o{0,1}’ 等價于 ‘o?’。請注意在逗號和兩個數之間不能有空格。

          3.5 定位符
            用來描述字符串或單詞的邊界,^和$分別指字符串的開始與結束,\b描述單詞的前或后邊界,\B表示非單詞邊界。不能對定位符使用限定符。

          3.6 選擇
            用圓括號將所有選擇項括起來,相鄰的選擇項之間用|分隔。但用圓括號會有一個副作用,是相關的匹配會被緩存,此時可用?:放在第一個選項前來消除這種副作用。
            其中?:是非捕獲元之一,還有兩個非捕獲元是?=和?!,這兩個還有更多的含義,前者為正向預查,在任何開始匹配圓括號內的正則表達式模式的位置來匹配搜索字符串,后者為負向預查,在任何開始不匹配該正則表達式模式的位置來匹配搜索字符串。

          3.7 后向引用
            對一個正則表達式模式或部分模式兩邊添加圓括號將導致相關匹配存儲到一個臨時緩沖區中,所捕獲的每個子匹配都按照在正則表達式模式中從左至右所遇到的內容存儲。存儲子匹配的緩沖區編號從 1 開始,連續編號直至最大 99 個子表達式。每個緩沖區都可以使用 ‘\n’ 訪問,其中 n 為一個標識特定緩沖區的一位或兩位十進制數。
            可以使用非捕獲元字符 ‘?:’, ‘?=’, or ‘?!’ 來忽略對相關匹配的保存。

          4. 各種操作符的運算優先級
            相同優先級的從左到右進行運算,不同優先級的運算先高后低。各種操作符的優先級從高到低如下:
            操作符 描述
          \ 轉義符
          (), (?:), (?=), [] 圓括號和方括號
          *, +, ?, {n}, {n,}, {n,m} 限定符
          ^, $, \anymetacharacter 位置和順序
          | “或”操作

          5. 全部符號解釋

          字符 描述
          \ 將下一個字符標記為一個特殊字符、或一個原義字符、或一個 向后引用、或一個八進制轉義符。例如,’n’ 匹配字符 “n”。’\n’ 匹配一個換行符。序列 ‘\\’ 匹配 “\” 而 “\(” 則匹配 “(”。
          ^ 匹配輸入字符串的開始位置。如果設置了 RegExp 對象的 Multiline 屬性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。
          $ 匹配輸入字符串的結束位置。如果設置了RegExp 對象的 Multiline 屬性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。
          * 匹配前面的子表達式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等價于{0,}。
          + 匹配前面的子表達式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等價于 {1,}。
          ? 匹配前面的子表達式零次或一次。例如,”do(es)?” 可以匹配 “do” 或 “does” 中的”do” 。? 等價于 {0,1}。
          {n} n 是一個非負整數。匹配確定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的兩個 o。
          {n,} n 是一個非負整數。至少匹配n 次。例如,’o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。’o{1,}’ 等價于 ‘o+’。’o{0,}’ 則等價于 ‘o*’。
          {n,m} m 和 n 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,”o{1,3}” 將匹配 “fooooood” 中的前三個 o。’o{0,1}’ 等價于 ‘o?’。請注意在逗號和兩個數之間不能有空格。
          ? 當該字符緊跟在任何一個其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面時,匹配模式是非貪婪的。非貪婪模式盡可能少的匹配所搜索的字符串,而默認的貪婪模式則盡可能多的匹配所搜索的字符串。例如,對于字符串 “oooo”,’o+?’ 將匹配單個 “o”,而 ‘o+’ 將匹配所有 ‘o’。
          . 匹配除 “\n” 之外的任何單個字符。要匹配包括 ‘\n’ 在內的任何字符,請使用象 ‘[.\n]’ 的模式。
          (pattern) 匹配 pattern 并獲取這一匹配。所獲取的匹配可以從產生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中則使用 $0…$9 屬性。要匹配圓括號字符,請使用 ‘\(’ 或 ‘\)’。
          (?:pattern) 匹配 pattern 但不獲取匹配結果,也就是說這是一個非獲取匹配,不進行存儲供以后使用。這在使用 “或” 字符 (|) 來組合一個模式的各個部分是很有用。例如, ‘industr(?:y|ies) 就是一個比 ‘industry|industries’ 更簡略的表達式。
          (?=pattern) 正向預查,在任何匹配 pattern 的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以后使用。例如,’Windows (?=95|98|NT|2000)’ 能匹配 “Windows 2000″ 中的 “Windows” ,但不能匹配 “Windows 3.1″ 中的 “Windows”。預查不消耗字符,也就是說,在一個匹配發生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預查的字符之后開始。
          (?!pattern) 負向預查,在任何不匹配 pattern 的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以后使用。例如’Windows (?!95|98|NT|2000)’ 能匹配 “Windows 3.1″ 中的 “Windows”,但不能匹配 “Windows 2000″ 中的 “Windows”。預查不消耗字符,也就是說,在一個匹配發生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預查的字符之后開始
          x|y 匹配 x 或 y。例如,’z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 則匹配 “zood” 或 “food”。
          [xyz] 字符集合。匹配所包含的任意一個字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。
          [^xyz] 負值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p'。
          [a-z] 字符范圍。匹配指定范圍內的任意字符。例如,’[a-z]’ 可以匹配 ‘a’ 到 ‘z’ 范圍內的任意小寫字母字符。
          [^a-z] 負值字符范圍。匹配任何不在指定范圍內的任意字符。例如,’[^a-z]’ 可以匹配任何不在 ‘a’ 到 ‘z’ 范圍內的任意字符。
          \b 匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
          \B 匹配非單詞邊界。’er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。
          \cx 匹配由 x 指明的控制字符。例如, \cM 匹配一個 Control-M 或回車符。x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個原義的 ‘c’ 字符。
          \d 匹配一個數字字符。等價于 [0-9]。
          \D 匹配一個非數字字符。等價于 [^0-9]。
          \f 匹配一個換頁符。等價于 \x0c 和 \cL。
          \n 匹配一個換行符。等價于 \x0a 和 \cJ。
          \r 匹配一個回車符。等價于 \x0d 和 \cM。
          \s 匹配任何空白字符,包括空格、制表符、換頁符等等。等價于 [ \f\n\r\t\v]。
          \S 匹配任何非空白字符。等價于 [^ \f\n\r\t\v]。
          \t 匹配一個制表符。等價于 \x09 和 \cI。
          \v 匹配一個垂直制表符。等價于 \x0b 和 \cK。
          \w 匹配包括下劃線的任何單詞字符。等價于’[A-Za-z0-9_]’。
          \W 匹配任何非單詞字符。等價于 ‘[^A-Za-z0-9_]’。
          \xn 匹配 n,其中 n 為十六進制轉義值。十六進制轉義值必須為確定的兩個數字長。例如,’\x41′ 匹配 “A”。’\x041′ 則等價于 ‘\x04′ & “1″。正則表達式中可以使用 ASCII 編碼。.
          \num 匹配 num,其中 num 是一個正整數。對所獲取的匹配的引用。例如,’(.)\1′ 匹配兩個連續的相同字符。
          \n 標識一個八進制轉義值或一個向后引用。如果 \n 之前至少 n 個獲取的子表達式,則 n 為向后引用。否則,如果 n 為八進制數字 (0-7),則 n 為一個八進制轉義值。
          \nm 標識一個八進制轉義值或一個向后引用。如果 \nm 之前至少有 nm 個獲得子表達式,則 nm 為向后引用。如果 \nm 之前至少有 n 個獲取,則 n 為一個后跟文字 m 的向后引用。如果前面的條件都不滿足,若 n 和 m 均為八進制數字 (0-7),則 \nm 將匹配八進制轉義值 nm。
          \nml 如果 n 為八進制數字 (0-3),且 m 和 l 均為八進制數字 (0-7),則匹配八進制轉義值 nml。
          \un 匹配 n,其中 n 是一個用四個十六進制數字表示的 Unicode 字符。例如, \u00A9 匹配版權符號 (?)。

           

          6. 部分例子

          正則表達式 說明
          /\b([a-z]+) \1\b/gi 一個單詞連續出現的位置
          /(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/ 將一個URL解析為協議、域、端口及相對路徑
          /^(?:Chapter|Section) [1-9][0-9]{0,1}$/ 定位章節的位置
          /[-a-z]/ A至z共26個字母再加一個-號。
          /ter\b/ 可匹配chapter,而不能terminal
          /\Bapt/ 可匹配chapter,而不能aptitude
          /Windows(?=95 |98 |NT )/ 可匹配Windows95或Windows98或WindowsNT,當找到一個匹配后,從Windows后面開始進行下一次的檢索匹配。

          7. 正則表達式匹配規則
          7.1 基本模式匹配

            一切從最基本的開始。模式,是正規表達式最基本的元素,它們是一組描述字符串特征的字符。模式可以很簡單,由普通的字符串組成,也可以非常復雜,往往用特殊的字符表示一個范圍內的字符、重復出現,或表示上下文。例如:

          ^once

            這個模式包含一個特殊的字符^,表示該模式只匹配那些以once開頭的字符串。例如該模式與字符串”once upon a time”匹配,與”There once was a man from NewYork”不匹配。正如如^符號表示開頭一樣,$符號用來匹配那些以給定模式結尾的字符串。

          bucket$

            這個模式與”Who kept all of this cash in a bucket”匹配,與”buckets”不匹配。字符^和$同時使用時,表示精確匹配(字符串與模式一樣)。例如:

          ^bucket$

            只匹配字符串”bucket”。如果一個模式不包括^和$,那么它與任何包含該模式的字符串匹配。例如:模式

          once

          與字符串

          There once was a man from NewYork
          Who kept all of his cash in a bucket.

          是匹配的。

            在該模式中的字母(o-n-c-e)是字面的字符,也就是說,他們表示該字母本身,數字也是一樣的。其他一些稍微復雜的字符,如標點符號和白字符(空格、制表符等),要用到轉義序列。所有的轉義序列都用反斜杠(\)打頭。制表符的轉義序列是:\t。所以如果我們要檢測一個字符串是否以制表符開頭,可以用這個模式:

          ^\t

          類似的,用\n表示“新行”,\r表示回車。其他的特殊符號,可以用在前面加上反斜杠,如反斜杠本身用\\表示,句號.用\.表示,以此類推。

          7.2 字符簇

          在INTERNET的程序中,正規表達式通常用來驗證用戶的輸入。當用戶提交一個form以后,要判斷輸入的電話號碼、地址、EMAIL地址、信用卡號碼等是否有效,用普通的基于字面的字符是不夠的。

          所以要用一種更自由的描述我們要的模式的辦法,它就是字符簇。要建立一個表示所有元音字符的字符簇,就把所有的元音字符放在一個方括號里:

          [AaEeIiOoUu]

          這個模式與任何元音字符匹配,但只能表示一個字符。用連字號可以表示一個字符的范圍,如:

          [a-z] //匹配所有的小寫字母
          [A-Z] //匹配所有的大寫字母
          [a-zA-Z] //匹配所有的字母
          [0-9] //匹配所有的數字
          [0-9\.\-] //匹配所有的數字,句號和減號
          [ \f\r\t\n] //匹配所有的白字符

          同樣的,這些也只表示一個字符,這是一個非常重要的。如果要匹配一個由一個小寫字母和一位數字組成的字符串,比如”z2″、”t6″或”g7″,但不是”ab2″、”r2d3″ 或”b52″的話,用這個模式:

          ^[a-z][0-9]$

          盡管[a-z]代表26個字母的范圍,但在這里它只能與第一個字符是小寫字母的字符串匹配。

          前面曾經提到^表示字符串的開頭,但它還有另外一個含義。當在一組方括號里使用^是,它表示“非”或“排除”的意思,常常用來剔除某個字符。還用前面的例子,我們要求第一個字符不能是數字:

          ^[^0-9][0-9]$

          這個模式與”&5″、”g7″及”-2″是匹配的,但與”12″、”66″是不匹配的。下面是幾個排除特定字符的例子:

          [^a-z] //除了小寫字母以外的所有字符
          [^\\\/\^] //除了(\)(/)(^)之外的所有字符
          [^\"\'] //除了雙引號(")和單引號(')之外的所有字符

          特殊字符”.” (點,句號)在正規表達式中用來表示除了“新行”之外的所有字符。所以模式”^.5$”與任何兩個字符的、以數字5結尾和以其他非“新行”字符開頭的字符串匹配。模式”.”可以匹配任何字符串,除了空串和只包括一個“新行”的字符串。

          PHP的正規表達式有一些內置的通用字符簇,列表如下:

          字符簇 含義
          [[:alpha:]] 任何字母
          [[:digit:]] 任何數字
          [[:alnum:]] 任何字母和數字
          [[:space:]] 任何白字符
          [[:upper:]] 任何大寫字母
          [[:lower:]] 任何小寫字母
          [[:punct:]] 任何標點符號
          [[:xdigit:]] 任何16進制的數字,相當于[0-9a-fA-F]

          7.3 確定重復出現

          到現在為止,你已經知道如何去匹配一個字母或數字,但更多的情況下,可能要匹配一個單詞或一組數字。一個單詞有若干個字母組成,一組數字有若干個單數組成。跟在字符或字符簇后面的花括號({})用來確定前面的內容的重復出現的次數。

          字符簇 含義
          ^[a-zA-Z_]$ 所有的字母和下劃線
          ^[[:alpha:]]{3}$ 所有的3個字母的單詞
          ^a$ 字母a
          ^a{4}$ aaaa
          ^a{2,4}$ aa,aaa或aaaa
          ^a{1,3}$ a,aa或aaa
          ^a{2,}$ 包含多于兩個a的字符串
          ^a{2,} 如:aardvark和aaab,但apple不行
          a{2,} 如:baad和aaa,但Nantucket不行
          \t{2} 兩個制表符
          .{2} 所有的兩個字符

          這些例子描述了花括號的三種不同的用法。一個數字,{x}的意思是“前面的字符或字符簇只出現x次”;一個數字加逗號,{x,}的意思是“前面的內容出現x或更多的次數”;兩個用逗號分隔的數字,{x,y}表示“前面的內容至少出現x次,但不超過y次”。我們可以把模式擴展到更多的單詞或數字:

          ^[a-zA-Z0-9_]{1,}$ //所有包含一個以上的字母、數字或下劃線的字符串
          ^[0-9]{1,}$ //所有的正數
          ^\-{0,1}[0-9]{1,}$ //所有的整數
          ^\-{0,1}[0-9]{0,}\.{0,1}[0-9]{0,}$ //所有的小數

          最后一個例子不太好理解,是嗎?這么看吧:與所有以一個可選的負號(\-{0,1})開頭(^)、跟著0個或更多的數字([0-9]{0,})、和一個可選的小數點(\.{0,1})再跟上0個或多個數字([0-9]{0,}),并且沒有其他任何東西($)。下面你將知道能夠使用的更為簡單的方法。

          特殊字符”?”與{0,1}是相等的,它們都代表著:“0個或1個前面的內容”或“前面的內容是可選的”。所以剛才的例子可以簡化為:

          ^\-?[0-9]{0,}\.?[0-9]{0,}$

          特殊字符”*”與{0,}是相等的,它們都代表著“0個或多個前面的內容”。最后,字符”+”與 {1,}是相等的,表示“1個或多個前面的內容”,所以上面的4個例子可以寫成:

          ^[a-zA-Z0-9_]+$ //所有包含一個以上的字母、數字或下劃線的字符串
          ^[0-9]+$ //所有的正數
          ^\-?[0-9]+$ //所有的整數
          ^\-?[0-9]*\.?[0-9]*$ //所有的小數

          當然這并不能從技術上降低正規表達式的復雜性,但可以使它們更容易閱讀。

          posted @ 2006-10-14 21:59 xyang 閱讀(373) | 評論 (0)編輯 收藏

          • Liferay - Liferay is designed to deploy portlets that adhere to the Portlet API (JSR 168). Many useful portlets are bundled with the portal (Mail, Document Library, Calendar, Message Boards, to name a few) and can be used as examples for adding your own custom portlets.
          • Exo - The eXo platform is a powerful Open Source - JSR 168 compliant - enterprise portal built from several modules. Based on the most innovative tools, API and frameworks such as Java Server Faces, Pico Container, JbossMX and AspectJ.
          • Pluto - Pluto is the Reference Implementation of the Java Portlet Specfication. The current version of this specification is JSR 168.
          • JA-SIG uPortal - uPortal is a free, sharable portal under development by institutions of higher-education. Community tools, such as chat, forums, survey, and so on, build relationships among campus constituencies. uPortal is an open-standard effort using Java, XML, JSP and J2EE.
          • Redhat Portal Server - Red Hat Portal Server is a open source Portal solution. Supports multiple languages in its user interface and pervasive devices such as WAP, XHTML, and VoiceXML in its rendering pipeline. Portals can be built and targeted for the individual, for work groups or teams, for people with a common set of interests, and for large corporations and organizations.
          • Jakarta Jetspeed 2 Enterprise Portal - Jetspeed is an Open Source implementation of an Enterprise Information Portal, using Java and XML. etspeed-2 is the next-generation enterprise portal at Apache. Jetspeed-2 offers several architectural enhancements and improvements over Jetspeed 1.0. First, Jetspeed-2 is conformant to the Java Portlet Standard and will provide a standard mechanism for the deployment of portlets.
          • Jahia - An integrated web content management and corporate portal server; 100% Java based; Available under a collaborative source license (contribue or pay paradigm); Installed in minutes; Easy to use and to administer; Full Multilanguage and I18N support; Staging environement; Content Workflow; Content Versioning; Document Management (WebDAV Support); Built-in Portlet-based interface; Built-in support for standardized java web applications and web services (default servlets supported as portlets); Full web-based administration; Integrated with the Apache Lucene Search Engine; LDAP compliant; JSP and JSTL support for easy templates development; Integrated HTML cache engine; dynamic XML export module and much more...
          • Gluecode Portal Foundation Server - Gluecode PFS is built in collaboration with the largest open source communities, including JBoss and Apache. It adheres to J2EE specifications, as well as implementations of portal industry standards.
          • jPortlet - jPortlet is not JSR 168 compliant, but the jPortlet API is very similar to the IBM WebSpere Portal Server.
          • GridSphere - 100% JSR 168 Portlet API compliant. Portlet API implementation nearly fully compatible with IBM's WebSphere 4.2. Higher-level model for building complex portlets using visual beans and the GridSphere User Interface (UI) tag library. Built-in support for Role Based Access Control (RBAC) separating users into guests, users, admins and super users. Persistence of data provided using Hibernate for RDBMS database support Integrated Junit/Cactus unit tests. Localization support including English, French, German, Czech, Polish, Hungarian and Italian.
          • Cocoon Portal Framework - Apache Cocoon is a web development framework built around the concepts of separation of concerns and component-based web development. Cocoon implements these concepts around the notion of 'component pipelines', each component on the pipeline specializing on a particular operation. The Portal Framework is based on Cocoon and is rumored to eventually support JSR-168.
          • jPorta - jPorta is a fully functional portal engine built on top of the Jeenius Framework (http://jeenius.sourceforge.net). It works with any 2.3 compilant servlet engine and comes with a number of useful gadgets.
          • MyPersonalizer - MyPersonalizer is a J2EE-based framework. The controller layer is built upon Jakarta Struts. MyPersonalizer also provides a number of command line administration tools for initialization tasks and a web administration tool to administrate any portal built with the framework.
          • oPortal - The OWASP Portal project, oPortal, is a portal written in java that aims to become the standard for secure web applications. The OWASP portal is based on the Jakarta Struts framework and designed with security as a REQUIREMENT, not an option. A reference implementation of a secure portal, that will rival the likes of any commercially available portal. JSR-168 compliance scheduled for version 1.1 release.
          • CHEF - CompreHensive collaborativeE Framework. CHEF is a Java J2EE (Servlet) based application server. The portal engine is a version of Apache's Jetspeed. CHEF is a set of tools and services. Tools control an application's user interface. Services provide information modeling, persistence, and important application logic. The tools are a set of groupware applications (such as chat, schedule and resources). The services specifically support the tools (such as content hosting and messaging) and generally support the application environment (such as authentication, event tracking, security).
          • Siemens Intranet Portal Framework - The Siemens Intranet Portal Framework (SIPF) offers a personalized, structured access to information and seamless integration of applications. A web-based work environment is realized within a browser by hierarchically structured virtual desktops.
          • Lutece - Lutece is a web portal engine that lets you quickly create internet or intranet dynamic sites based on HTML, XML or database contents. This tool, developed by the Data Processing Department of the City of Paris for the districts web sites projects, is now used by more than 18 web sites of the city.
          • Sakai Project - Builds on JSR 168 and OKI open service interface definitions. A re-factored set of educational software tools that blends the best of features from the University of Michigan, Indiana University, MIT, Stanford, and the uPortal consortium. The Sakai Project will include an Enterprise Services-based Portal, a complete Course Management System with sophisticated assessment tools, a Research Support Collaboration System, a Workflow Engine, and a Technology Portability Profile as a clear standard for writing future tools that can extend this core set of educational applications. The Sakai Project Core universities are committing over $2 million per year to launch and support this two year project.
          • JBoss Portal - JBoss Portal 2.0 framework and architecture includes the portal container and supports a wide range of features including standard portlets, single sign-on, clustering and internationalization. Portal themes and layouts are configurable. Fine-grained security administration down to portlet permissions rounds out the security model. JBoss Portal 2.0 includes a rich content management system and message board support.
          • Stringbeans - Stringbeans is a platform for building enterprise information portals. The platform is composed of three components: a portal container/server, a Web Services framework, and a process automation engine. Compatible with JSR 168 standard, mobile client support (WML 1.1 and XHTML MP 1.0), JAAS-based user authentication, portlets capable of displaying RSS headlines, multi-page tabular data from database tables, reports, charts, XML documents via XSL tranformations. Stringbeans is deployed as a J2EE Web application in a container that supports Servlets 2.3 and Java Server Pages (JSP) 1.2 specification. EJB support is not required.
          • InfoGlue 2.0 - InfoGlue is a GPL-based content management and JSR 168 Portal system. Key features includes full multi-language support, excellent information reuse between sites and extensive integration capabilities. A dynamic visual page builder. This release supports advanced workflows as well as very detailed access control both internally and externally.
          • NodeVision Portal - NVPortal is the Java Enterprise JSR 168 compliant Portal solution based on a BSD-License. Features include a Business Process Engine and Search Engine based on SOAP, WSRP compliance, Multilingual, Single Sign On and a Graphical administration interface.
          • Pentaho - The Pentaho BI Project provides enterprise-class reporting, analysis, dashboard, data mining and workflow capabilities that help organizations operate more efficiently and effectively. The software offers flexible deployment options that enable use as embeddable components, customized BI application solutions, and as a complete out-of-the-box, integrated BI platform.
          • IPoint Open Edition - iPoint Open Edition has passed the JSR168 TCK. It is designed so that the portal can be developed within a browser. iPoint portal contains many prebuilt portlets and features complete browser based management and site construction.
          • Portals in Cocoon - The portal framework is a portal server that runs inside Cocoon - or to be more precise inside the Cocoon servlet. It contains a portlet container that is called coplet container. Coplet stands for Cocoon Portlet and is the Cocoon equivalent to portlet. The new portal engine is a replacement implementation of a portal engine which focuses on more flexibility and ease-of-use. In addition it supports the JSR-168.
          • Enterprise-class Portal Server Open Source project - The Portal Server open source project is derived from the Sun Java System Portal Server 7 product and will comprise of the following components and technologies: Portlet repository, JSR168 compliant portlet container, Web Services for Remote Portlets (WSRP) 1.0 based producer and consumer implementations, Portal aggregation and administration framework, Communities and collaboration framework/services, Full-text search engine with federated search and taxonomy capabilities, Secure remote access for SSL/VPN capabilities from outside the firewall and Multi-device mobile access capability to all portal content and applications.

          posted @ 2006-10-10 09:44 xyang 閱讀(669) | 評論 (0)編輯 收藏

          1.?自動裝箱與拆箱?對應C#
          ?例1.1
          ??Integer?i?=?10;
          ??int?j?=?i;
          ??
          2.?更優化的for循環?對應就C#---foreach循環
          ?例2.1
          ??String[]?names?=?{"BadBoy","GoodBoy","HappyGirl","sadGirl"};
          ??for(String?option:?names)?{
          ???System.out.println(option);
          ??}
          ?例2.2?加泛型?對應C++模板
          ??import?java.util.*;
          ??
          ??ArrayList<String>?animals?=?new?ArrayList<String>();
          ??animals.add("Dog");
          ??animals.add("Cat");
          ??animals.add("Chick");
          ??animals.add("Cow");
          ??for(String?option?:?animals)?{
          ???System.out.println(option);
          ??}
          ??
          3.參數可變的方法和printf
          ?例3.1
          ??定義:
          ??public?int?sum(int...?n)?{??//傳過來n為一個int型數組
          ???int?tempSum;
          ???for(int?option?:?n)?{
          ????tempSum+=option;
          ???}
          ???/*
          ???for(int?i?=?0;?i?<?n.length;?i++)?{
          ????tempSum+=n[i];
          ???}
          ???*/
          ???return?tempSum;
          ??}
          ??調用1:?sum(1);
          ??調用2:?sum(1,2);
          ??調用3:?sum(1,2,3,4);
          ?例3.2?printf方法,??對應c語言的printf
          ??int?x?=?10;
          ??int?y?=?20;
          ??int?sum?=?x?+?y;
          ??System.out.printf("%d?+?%d?=?%d",x,y,sum);
          4.?枚舉
          ?例4.1
          ??public?enum?MyColors?{
          ???red,
          ???black,
          ???blue,
          ???green,
          ???yellow
          ??}
          ??
          ??MyColors?color?=?MyColors.red;
          ??for(MyColors?option?:?color.values())?{
          ???System.out.println(option);
          ??}

          /**不能在switch語句里這樣寫case?MyColors.red:
          ?*這樣編譯器不會讓你通過*/
          switch(color)?{
          ?case?red:
          ??System.out.println("best?color?is?"+red);
          ??break;
          ?case?black:
          ??System.out.println("NO?"?+?black);
          ??break;
          ?default:
          ??System.out.println("What");
          ??break;
          }

          5.靜態引用
          ?例5.1
          ??1.5版本以前的寫法是:
          ?
          ??  import?java.lang.Math;?//程序開頭處
          ??
          ??  ...
          ??
          ??  double?x?=?Math.random();?
          ??1.5版本中可以這樣寫
          ???import?static?java.lang.Math.random;?//程序開頭處
          ???
          ???...
          ??  
          ???double?x?=?random();??

          posted @ 2006-10-09 23:05 xyang 閱讀(276) | 評論 (0)編輯 收藏

          這個題目含有許多需要解釋的概念,最容易說明的是“站內消息”,這是很多論壇都有的功能,可以通過web向其他的在線用戶發送消息,很多用戶都使用過。站內消息的第一個好處是大家都不需要安裝客戶端,你不用知道對方的MSN或者QQ,就能與他聯系,稱贊他的觀點或者是給他一頓臭罵。第二個好處是客戶管理方便,利用session來維護在線名單,各種腳本都已經把session操作封裝得很易用了,不用像其他無狀態的即時通信工具(比如使用UDP通信的工具)一樣,要費一些腦細胞來解決在線名單的問題。缺點嘛,就是實時性不好,一般是在用戶跳轉或者刷新頁面才能探測消息、更新在線名單。

            Session監聽嘛,沒什么好解釋的,java提供了很靈活的事件機制來監聽session,可以監聽session的創建和銷毀,監控session所攜帶數據的創建、變化和銷毀,可以監聽session的銳化和鈍化(了解對象序列化的兄弟應該知道這個),其他的平臺是個什么情況我不太清楚,估計也差不多吧。如果能夠對所有客戶的session進行監控,就不用再去操作麻煩而危險的Application了。

            Xmlhttp是MS推的一項技術,功能很復雜,可以做很多事情,比如客戶端可以在簡單的HTML中打開HTTP連接,主動向server請求數據并獲得返回數據,是DOM技術一個非常重要的應用,利用它來寫無刷新的動態頁面簡直是so?easy,做過web開發的兄弟應該明白它的意義有多么重大。

          一、?session監聽

            servlet中對session的監聽有很多接口,功能很靈活,最常用的是監聽Session和Attribute。這里要澄清一下概念,servlet中的session監聽和Attribute監聽含義有差別,session監聽指的不是我們一般所理解的放置一個session或者銷毀一個session,這是Attribute監聽的功能,因為servlet中放置session的語法是session.setAttribute(“session名”,要放入的對象)。而session監聽,監聽的是HTTP連接,只要有用戶與server連接,就算連接的是一個空白的jsp頁面,也會觸發session事件,所以此處的session實際上指的是connection,用來統計當前在線用戶數最合適了。不知道我說清楚了沒有。下面分別講解這兩種監聽方式。

          1、?session監聽

            首先編寫一個session監聽類,實作HttpSessionListener接口,它的作用是計算當前有多少個在線用戶:

          1. /**
          2. *@Author?bromon
          3. *2004-6-12
          4. */
          5. package?org.bromon.test;
          6. import?javax.servlet.*;
          7. import?javax.servlet.http.*;
          8. public?class?SessionCount?implements?HttpSessionListener
          9. {
          10. ????private?static?int?count=0;
          11. ????public?void?sessionCreated(HttpSessionEvent?se)
          12. ????{
          13. ????????count++;
          14. ????????System.out.println(“session創建:”+new?java.util.Date());
          15. ????}
          16. ????public?void?sessionDestroyed(HttpSessionEvent?se)
          17. ????{
          18. ???????count--;
          19. ???????System.out.println(“session銷毀:”+new?java.util.Date());
          20. ????}
          21. ????public?static?int?getCount()
          22. ????{
          23. ???????return(count);
          24. ?????}
          25. }



            怎么樣,是不是一目了然?count被定義為static,是因為要保證整個系統只有這一個count。如果你實在不放心,可以把它寫成一個單例類。

            然后在web.xml中聲明這個監聽器:
          <listener>
          <listener-class>
          org.bromon.test.SessionCount
          </listener-class>
          </listener>

            編寫一個測試頁面test.jsp,內容是獲得count:
          <%
          int?count=org.bromon.test.SessionCount.getCount();
          out.println(count);
          %>

            需要注意的是,這里根本不涉及任何session的操作。重啟動App?server,試著連接test.jsp,可以看到監聽器已經開始工作。

          2、?Attribute監聽
            作為一個站內消息系統,肯定要獲得所有登陸者的ID,才有可能互發消息。這就涉及Attribute監聽。假設我們寫了個用戶登陸的模塊,用戶通過身份驗證之后會產生一個session,保存它的相關信息,比如:
          1. //check.jsp
          2. <%
          3. ????String?name=request.getParameter(“name”);
          4. ????Name=new?String(name.getBytes(“ISO8859-1”));
          5. ????session.setAttribute(“user”,name);
          6. %>


            做過jsp的兄弟應該對這段代碼再熟悉不過了,下面寫個監聽器來監聽用戶登陸,把所有用戶的ID保存到一個List當中,這個監聽器實作HttpSessionAttributeListener接口:

          1. /**
          2. *@Author?bromon
          3. *2004-6-12
          4. */
          5. package?org.bromon.test;
          6. import?javax.servlet.*;
          7. import?javax.servlet.http.*;
          8. import?java.util.*;
          9. public?class?OnlineList?implements?HttpSessionAttributeListener
          10. {
          11. ????private?static?List?list=new?ArrayList();
          12. ????public?void?attributeAdded(HttpSessionBindingEvent?se)
          13. ????{
          14. ????????if(“user”.equals(se.getName()))
          15. ????????{
          16. ????????????list.add(se.getValue());
          17. ?????????}
          18. ????}
          19. ????public?void?attributeRemoved(HttpSessionBindingEvent?se)
          20. ????{
          21. ?????????if(“user”.equals(se.getName()))
          22. ?????????{
          23. ????????????list.remove(se.getValue());
          24. ?????????}
          25. ????}
          26. ????public?void?attributeReplaced(HttpSessionBindingEvent?se){}
          27. ????public?static?List?getList()
          28. ????{
          29. ?????????return(list);
          30. ?????}
          31. }


          寫個簡單的jsp來得到用戶列表:
          <%
          ????java.util.List?list=org.bromon.test.OnlineList.getList();
          ????out.println(“共有”+list.size()+”名用戶已登陸:”);
          ????for(int?I=0;I<lise.size();i++)
          ????{
          ????????out.println(list.get(i));
          ????}
          %>

          也許你說,這有什么神奇呢,監聽session而已,不著急,看看xmlhttp。

          二、?XMLHTTP

            XMLHTTP的用處很多,這里只說我們需要的,就是無刷新的與server通信,看這段代碼:

          1. <script?language="javascript">?
          2. xml?=?new?ActiveXObject("Microsoft.XMLHTTP");?
          3. var?post="?";//構造要攜帶的數據?
          4. xml.open("POST","http://localhost:7001/TestWL/index.jsp",false);//使用POST方法打開一個到服務器的連接,以異步方式通信?
          5. xml.setrequestheader("content-length",post.length);?
          6. xml.setrequestheader("content-type","application/x-www-form-urlencoded");?
          7. xml.send(post);//發送數據?
          8. var?res?=?xml.responseText;//接收服務器返回的數據?
          9. document.write(res);?
          10. </script>



            豁然開朗,這段代碼就是打開一個HTTP連接,以標準的HTTP格式傳遞數據,如果你喜歡,可以用XML的格式來傳遞。更改一下xml對象的構造方式就可以兼容Mozilla和Netscape。下面來寫一個輪詢,每隔一段時間刷新一次用戶列表,當然,是不需要刷新頁面的:

          1. <html>
          2. <head><title>探測器</title>
          3. <script?language="javascript">
          4. function?detect()
          5. {
          6. xml?=?new?ActiveXObject("Microsoft.XMLHTTP");?
          7. var?post="?";//構造要攜帶的數據?
          8. xml.open("POST","http://localhost:7001/TestWL/index.jsp",false);//使用POST方法打開一個到服務器的連接,以異步方式通信?
          9. xml.setrequestheader("content-length",post.length);?
          10. xml.setrequestheader("content-type","application/x-www-form-urlencoded");?
          11. xml.send(post);//發送數據?
          12. var?res?=?xml.responseText;//接收服務器返回的數據?
          13. list.innerText=res;
          14. setTimeout(“detect()”,5000);//每隔5秒鐘輪詢一次
          15. }?
          16. </script>
          17. <body?onload=”detect()”>
          18. <a?id=”list”></a>
          19. </body>
          20. </html>
          21. 這樣的通信方式數據量很小,不用重新傳遞整個頁面,5秒鐘輪一次,普通PC也能承受較大的在線數。構造一個探測器來監聽在線列表和消息,效果是很好的,即使你的客戶坐在電腦前袖手旁觀,鍵鼠都不碰一下,也能保證數據即時傳遞,頁面也不會發生跳轉和刷新。

              Session監聽加上XMLHTTP通信,開發一個較為完善的站內消息系統實在易如反掌

          posted @ 2006-10-09 22:58 xyang 閱讀(1418) | 評論 (1)編輯 收藏

          計算機常用英語
          計算機常用英語術語、詞匯表
          Computer Vocabulary In Common [color=darkblue][/color]Use
          一、硬件類(Hardware)
          二、軟件類(Software)
          三、網絡類(Network)
          四、其它

          CPU(Center Processor Unit)中央處理單元
          mainboard主板
          RAM(random access
          memory)隨機存儲器(內存)
          ROM(Read Only Memory)只讀存儲器
          Floppy Disk軟盤
          Hard Disk硬盤
          CD-ROM光盤驅動器(光驅)
          monitor監視器
          keyboard鍵盤
          mouse鼠標
          chip芯片
          CD-R光盤刻錄機
          HUB集線器
          Modem= MOdulator-DEModulator,調制解調器
          P-P(Plug and Play)即插即用
          UPS(Uninterruptable Power Supply)不間斷電源
          BIOS(Basic-input-Output
          System)基本輸入輸出系統
          CMOS(Complementary Metal-Oxide-Semiconductor)互補金屬氧化物半導體
          setup安裝
          uninstall卸載
          wizzard向導
          OS(Operation Systrem)操作系統
          OA(Office AutoMation)辦公自動化
          exit退出
          edit編輯
          copy復制
          cut剪切
          paste粘貼
          delete刪除
          select選擇
          find查找
          select all全選
          replace替換
          undo撤消
          redo重做
          program程序
          license許可(證)
          back前一步
          next下一步
          finish結束
          folder文件夾
          Destination Folder目的文件夾
          user用戶
          click點擊
          double click雙擊
          right click右擊
          settings設置
          update更新
          release發布
          data數據
          data base數據庫
          DBMS(Data Base Manege
          System)數據庫管理系統
          view視圖
          insert插入
          object對象
          configuration配置
          command命令
          document文檔
          POST(power-on-self-test)電源自檢程序
          cursor光標
          attribute屬性
          icon圖標
          service pack服務補丁
          option pack功能補丁
          Demo演示
          short cut快捷方式
          exception異常
          debug調試
          previous前一個
          column行
          row列
          restart重新啟動
          text文本
          font字體
          size大小
          scale比例
          interface界面
          function函數
          access訪問
          manual指南
          active激活
          computer language計算機語言
          menu菜單
          GUI(graphical user
          interfaces )圖形用戶界面
          template模版
          page setup頁面設置
          password口令
          code密碼
          print preview打印預覽
          zoom in放大
          zoom out縮小
          pan漫游
          cruise漫游
          full screen全屏
          tool bar工具條
          status bar狀態條
          ruler標尺
          table表
          paragraph段落
          symbol符號
          style風格
          execute執行
          graphics圖形
          image圖像
          Unix用于服務器的一種操作系統
          Mac OS蘋果公司開發的操作系統
          OO(Object-Oriented)面向對象
          virus病毒
          file文件
          open打開
          colse關閉
          new新建
          save保存
          exit退出
          clear清除
          default默認
          LAN局域網
          WAN廣域網
          Client/Server客戶機/服務器
          ATM( Asynchronous
          Transfer Mode)異步傳輸模式
          Windows NT微軟公司的網絡操作系統
          Internet互聯網
          WWW(World Wide Web)萬維網
          protocol協議
          HTTP超文本傳輸協議
          FTP文件傳輸協議
          Browser瀏覽器
          homepage主頁
          Webpage網頁
          website網站
          URL在Internet的WWW服務程序上
          用于指定信息位置的表示方法
          Online在線
          Email電子郵件
          ICQ網上尋呼
          Firewall防火墻
          Gateway網關
          HTML超文本標識語言
          hypertext超文本
          hyperlink超級鏈接
          IP(Address)互聯網協議(地址)
          SearchEngine搜索引擎
          TCP/IP用于網絡的一組通訊協議
          Telnet遠程登錄
          IE(Internet Explorer)探索者(微軟公司的網絡瀏覽器)
          Navigator引航者(網景公司的瀏覽器)
          multimedia多媒體
          ISO國際標準化組織
          ANSI美國國家標準協會
          able 能
          activefile 活動文件
          addwatch 添加監視點
          allfiles 所有文件
          allrightsreserved 所有的權力保留
          altdirlst 切換目錄格式
          andfixamuchwiderrangeofdiskproblems 并能夠解決更大范圍內的磁盤問題
          andotherinFORMation 以及其它的信息
          archivefileattribute 歸檔文件屬性
          assignto 指定到
          autoanswer 自動應答
          autodetect 自動檢測
          autoindent 自動縮進
          autosave 自動存儲
          availableonvolume 該盤剩余空間
          badcommand 命令錯
          badcommandorfilename 命令或文件名錯
          batchparameters 批處理參數
          binaryfile 二進制文件
          binaryfiles 二進制文件
          borlandinternational borland國際公司
          bottommargin 頁下空白
          bydate 按日期
          byextension 按擴展名
          byname 按名稱
          bytesfree 字節空閑
          callstack 調用棧
          casesensitive 區分大小寫
          causespromptingtoconfirmyouwanttooverwritean 要求出現確認提示,在你想覆蓋一個
          centralpointsoftwareinc central point 軟件股份公司
          changedirectory 更換目錄
          changedrive 改變驅動器
          changename 更改名稱
          characterset 字符集
          checkingfor 正在檢查
          checksadiskanddisplaysastatusreport 檢查磁盤并顯示一個狀態報告
          chgdrivepath 改變盤/路徑
          china 中國
          chooseoneofthefollowing 從下列中選一項
          clearall 全部清除
          clearallbreakpoints 清除所有斷點
          clearsanattribute 清除屬性
          clearscommandhistory 清除命令歷史
          clearscreen 清除屏幕
          closeall 關閉所有文件
          codegeneration 代碼生成
          colorpalette 彩色調色板
          commandline 命令行
          commandprompt 命令提示符
          compressedfile 壓縮文件
          configuresaharddiskforusewithmsdos 配置硬盤,以為 MS-DOS 所用
          conventionalmemory 常規內存
          copiesdirectoriesandsubdirectorie***ceptemptyones 拷貝目錄和子目錄,空的除外
          copiesfileswiththearchiveattributeset 拷貝設置了歸檔屬性的文件
          copiesoneormorefilestoanotherlocation 把文件拷貝或搬移至另一地方
          copiesthecontentsofonefloppydisktoanother 把一個軟盤的內容拷貝到另一個軟盤上
          copydiskette 復制磁盤
          copymovecompfindrenamedeletevervieweditattribwordpprintlist C拷貝M移動 O比 F搜索R改名 D刪除 V版本 E瀏覽A屬性 W寫字 P打印 L列表
          copyrightc 版權(c
          createdospartitionorlogicaldosdrive 創建DOS分區或邏輯DOS驅動器
          createextendeddospartition 創建擴展DOS分區
          createlogicaldosdrivesintheextendeddospartition 在擴展DOS分區中創建邏輯DOS驅動器
          createprimarydospartition 創建DOS主分區
          createsadirectory 創建一個目錄
          createschangesordeletesthevolumelabelofadisk 創建,改變或刪除磁盤的卷標
          currentfile 當前文件
          currentfixeddiskdrive 當前硬盤驅動器
          currentsettings 當前設置
          currenttime 當前時間
          cursorposition 光標位置
          defrag 整理碎片
          dele 刪去
          deletepartitionorlogicaldosdrive 刪除分區或邏輯DOS驅動器
          deletesadirectoryandallthesubdirectoriesandfilesinit 刪除一個目錄和所有的子目錄及其中的所有文件
          deltree 刪除樹
          devicedriver 設備驅動程序
          dialogbox 對話欄
          directionkeys 方向鍵
          directly 直接地
          directorylistargument 目錄顯示變量
          directoryof 目錄清單
          directorystructure 目錄結構
          diskaccess 磁盤存取
          diskcopy 磁盤拷貝
          diskservicescopycomparefindrenameverifyvieweditmaplocateinitialize 磁盤服務功能: C拷貝 O比較 F搜索R改卷名V校驗 瀏覽E編緝M圖 L找文件 N格式化
          diskspace 磁盤空間
          displayfile 顯示文件
          displayoptions 顯示選項
          displaypartitioninFORMation 顯示分區信息
          displaysfilesinspecifieddirectoryandallsubdirectories 顯示指定目錄和所有目錄下的文件
          displaysfileswithspecifiedattributes 顯示指定屬性的文件
          displaysorchangesfileattributes 顯示或改變文件屬性
          displaysorsetsthedate 顯示或設備日期
          displayssetupscreensinmonochromeinsteadofcolor 以單色而非彩色顯示安裝屏信息
          displaystheamountofusedandfreememoryinyoursystem 顯示系統中已用和未用的內存數量
          displaysthefullpathandnameofeveryfileonthedisk 顯示磁盤上所有文件的完整路徑和名稱
          displaysthenameoforchangesthecurrentdirectory 顯示或改變當前目錄
          doctor 醫生
          doesn 不
          doesntchangetheattribute 不要改變屬性
          dosshell DOS 外殼
          doubleclick 雙擊
          doyouwanttodisplaythelogicaldriveinFORMationyn 你想顯示邏輯驅動器信息嗎(y/n)?
          driveletter 驅動器名
          editmenu 編輯選單
          emsmemory ems內存
          endoffile 文件尾
          endofline 行尾
          enterchoice 輸入選擇
          entiredisk 轉換磁盤
          environmentvariable 環境變量
          esc esc
          everyfileandsubdirectory 所有的文件和子目錄
          existingdestinationfile 已存在的目錄文件時
          expandedmemory 擴充內存
          expandtabs 擴充標簽
          explicitly 明確地
          extendedmemory 擴展內存
          fastest 最快的
          fatfilesystem fat 文件系統
          fdiskoptions fdisk選項
          fileattributes 文件屬性
          fileFORMat 文件格式
          filefunctions 文件功能
          fileselection 文件選擇
          fileselectionargument 文件選擇變元
          filesin 文件在
          filesinsubdir 子目錄中文件
          fileslisted 列出文件
          filespec 文件說明
          filespecification 文件標識
          filesselected 選中文件
          findfile 文件查尋
          fixeddisk 硬盤
          fixeddisksetupprogram 硬盤安裝程序
          fixeserrorsonthedisk 解決磁盤錯誤
          floppydisk 軟盤
          FORMatdiskette 格式化磁盤
          FORMatsadiskforusewithmsdos 格式化用于MS-DOS的磁盤
          FORMfeed 進紙
          freememory 閑置內存
          fullscreen 全屏幕
          functionprocedure 函數過程
          graphical 圖解的
          graphicslibrary 圖形庫
          groupdirectoriesfirst 先顯示目錄組
          hangup 掛斷
          harddisk 硬盤
          hardwaredetection 硬件檢測
          hasbeen 已經
          helpfile 幫助文件
          helpindex 幫助索引
          helpinFORMation 幫助信息
          helppath 幫助路徑
          helpscreen 幫助屏
          helptext 幫助說明
          helptopics 幫助主題
          helpwindow 幫助窗口
          hiddenfile 隱含文件
          hiddenfileattribute 隱含文件屬性
          hiddenfiles 隱含文件
          howto 操作方式
          ignorecase 忽略大小寫
          inbothconventionalanduppermemory 在常規和上位內存
          incorrectdos 不正確的DOS
          incorrectdosversion DOS 版本不正確
          indicatesabinaryfile 表示是一個二進制文件
          indicatesanasciitextfile 表示是一個ascii文本文件
          insertmode 插入方式
          insteadofusingchkdsktryusingscandisk 請用scandisk,不要用chkdsk
          inuse 在使用
          invaliddirectory 無效的目錄
          is 是
          kbytes 千字節
          keyboardtype 鍵盤類型
          labeldisk 標注磁盤
          laptop 膝上
          largestexecutableprogram 最大可執行程序
          largestmemoryblockavailable 最大內存塊可用
          lefthanded 左手習慣
          leftmargin 左邊界
          linenumber 行號
          linenumbers 行號
          linespacing 行間距
          listbyfilesinsortedorder 按指定順序顯示文件
          listfile 列表文件
          listof 清單
          locatefile 文件定位
          lookat 查看
          lookup 查找
          macroname 宏名字
          makedirectory 創建目錄
          memoryinfo 內存信息
          memorymodel 內存模式
          menubar 菜單條
          menucommand 菜單命令
          menus 菜單
          messagewindow 信息窗口
          microsoft 微軟
          microsoftantivirus 微軟反病毒軟件
          microsoftcorporation 微軟公司
          mini 小的
          modemsetup 調制解調器安裝
          modulename 模塊名
          monitor mode 監控狀態
          monochromemonitor 單色監視器
          move to 移至
          multi 多
          newdata 新建數據
          newer 更新的
          newfile 新文件
          newname 新名稱
          newwindow 新建窗口
          norton norton
          nostack 棧未定義
          noteusedeltreecautiously 注意:小心使用deltree
          onlinehelp 聯機求助
          optionally 可選擇地
          or 或
          pageframe 頁面
          pagelength 頁長
          pausesaftereachscreenfulofinFORMation 在顯示每屏信息后暫停一下
          pctools pc工具
          postscript 附言
          prefixmeaningnot 前綴意即\"不
          prefixtoreverseorder 反向顯示的前綴
          presetswitchesbyprefixinganyswitchwithhyphenforexamplew 用前綴和放在短橫線-后的開關(例如/-w)預置開關
          pressakeytoresume 按一鍵繼續
          pressanykeyforfilefunctions 敲任意鍵執行文件功能
          pressentertokeepthesamedate 敲回車以保持相同的日期
          pressentertokeepthesametime 敲回車以保持相同的時間
          pressesctocontinue 敲esc繼續
          pressesctoexit 敲<esc>鍵退出
          pressesctoexitfdisk 敲esc退出fdisk
          pressesctoreturntofdiskoptions 敲esc返回fdisk選項
          previously 在以前
          printall 全部打印
          printdevice 打印設備
          printerport 打印機端口
          processesfilesinalldirectoriesinthespecifiedpath 在指定的路徑下處理所有目錄下的文件
          programfile 程序文件
          programmingenvironment 程序設計環境
          promptsyoubeforecreatingeachdestinationfile 在創建每個目標文件時提醒你
          promptsyoutopressakeybeforecopying 在拷貝前提示你敲一下鍵
          pulldown 下拉
          pulldownmenus 下拉式選單
          quickFORMat 快速格式化
          quickview 快速查看
          readonlyfile 只讀文件
          readonlyfileattribute 只讀文件屬性
          readonlyfiles 只讀文件
          readonlymode 只讀方式
          redial 重撥
          repeatlastfind 重復上次查找
          reportfile 報表文件
          resize 調整大小
          respectively 分別地
          rightmargin 右邊距
          rootdirectory 根目錄
          runsdebugaprogramtestingandeditingtool 運行debug, 它是一個測試和編輯工具
          runtimeerror 運行時出錯
          save all 全部保存
          save as 另存為
          scandisk 磁盤掃描程序
          scandiskcanreliablydetect scandisk可以可靠地發現
          screencolors 屏幕色彩
          screenoptions 屏幕任選項
          screensaver 屏幕暫存器
          screensavers 屏幕保護程序
          screensize 屏幕大小
          scrollbars 翻卷欄
          scrolllockoff 滾屏已鎖定
          searchfor 搜索
          sectorspertrack 每道扇區數
          selectgroup 選定組
          selectionbar 選擇欄
          setactivepartition 設置活動分區
          setupoptions 安裝選項
          shortcutkeys 快捷鍵
          showclipboard 顯示剪貼板
          singleside 單面
          sizemove 大小/移動
          sorthelp S排序H幫助
          sortorder 順序

          posted @ 2006-10-07 21:22 xyang 閱讀(343) | 評論 (0)編輯 收藏

          HashTable的應用非常廣泛,HashMap是新框架中用來代替HashTable的類,也就是說建議使用HashMap,不要使用HashTable。可能你覺得HashTable很好用,為什么不用呢?這里簡單分析他們的區別。?
          1.HashTable的方法是同步的,HashMap未經同步,所以在多線程場合要手動同步HashMap這個區別就像Vector和ArrayList一樣。

          2.HashTable不允許null值(key和value都不可以),HashMap允許null值(key和value都可以)。

          3.HashTable有一個contains(Object?value),功能和containsValue(Object?value)功能一樣。

          4.HashTable使用Enumeration,HashMap使用Iterator。

          以上只是表面的不同,它們的實現也有很大的不同。

          5.HashTable中hash數組默認大小是11,增加的方式是?old*2+1。HashMap中hash數組的默認大小是16,而且一定是2的指數。

          6.哈希值的使用不同,HashTable直接使用對象的hashCode,代碼是這樣的:
          int?hash?=?key.hashCode();
          int?index?=?(hash?&?0x7FFFFFFF)?%?tab.length;
          而HashMap重新計算hash值,而且用與代替求模:
          int?hash?=?hash(k);
          int?i?=?indexFor(hash,?table.length);

          static?int?hash(Object?x)?{
            int?h?=?x.hashCode();

            h?+=?~(h?<<?9);
            h?^=?(h?>>>?14);
            h?+=?(h?<<?4);
            h?^=?(h?>>>?10);
            return?h;
          }
          static?int?indexFor(int?h,?int?length)?{
            return?h?&?(length-1);
          }
          以上只是一些比較突出的區別,當然他們的實現上還是有很多不同的,比如
          HashMap對null的操作

          posted @ 2006-09-30 21:44 xyang 閱讀(920) | 評論 (0)編輯 收藏

          ?1 public ? class ?hello? {
          ?2 ???? public ? static ? void ?main(String?a[])? throws ?java.io.IOException? {
          ?3 ????????String?tmp? = ? " 中文 " ;?
          ?4 ????????printHex(tmp, " Unicode " );
          ?5 ????????printHex(tmp, " GB2312 " );
          ?6 ????????printHex(tmp, " ISO8859-1 " );
          ?7 ????????printHex(tmp, " UTF-8 " );
          ?8 ????}

          ?9
          10 ???? private ? static ? void ?printHex(String?str,String?charset)? throws ?java.io.IOException? {
          11 ???????? byte []?buf? = ?str.getBytes(charset);
          12 ???????? for ?( int ?i? = ? 0 ;?i? < ?buf.length;?i ++ )? {
          13 ????????????System.out.print(Integer.toHexString(buf[i]));
          14 ????????????System.out.print( " ? " );
          15 ????????}

          16 ????????System.out.println( " ? " );
          17 ????}

          18
          19 }

          posted @ 2006-09-28 13:42 xyang 閱讀(218) | 評論 (0)編輯 收藏

          [概述]
          ????? 計算機中的一切都是以數字來表示的,字符同樣如此。字符編碼就是將字符集編碼成為數字序列,以便能讓計算機識別。各個地區和國家使用的語言有別,將本地使用的語言符號進行編碼就得到本地編碼字符集。例如西歐國家使用的本地編碼是ISO8859-1,中國大陸和新加坡等地區使用本地編碼是GB2312或GBK,中國港臺地區使用的本地編碼是BIG5,韓國和日本的本地編碼分別是euc-kr和Shift_JIS。電腦的操作系統支持各種本地編碼字符集,操作系統默認的本地編碼和你所安裝的操作系統語言版本是一致的。本地集只對本地使用的文字符號進行了編碼,并不包括其他地區使用的文字,即使兩個本地集中包含了相同的字符,這個字符的編碼值也是不同的。例如“中”的GB2312或GBK編碼值為“0xD6D0”,而BIG5編碼值為“0xA4A4”。
          ????? 全球信息交流與融合的趨勢要求實現對本地字符集的統一,1984年4月ISO成立了工作組,針對各國文字、符號進行統一編碼,這種編碼成為Unicode。Unicode于1992年6月通過DIS(DrafInternationalStandard),V2.0版本于1996年發布。Unicode編碼包括了符號6811個、漢字20902個、韓文11172個、等等。Unicode雖然實現了全球統一編碼,但是在字符集數量和編碼效率方面顯然存在著不足,而UTF-8、UTF-16就是針對Unicode編碼進行轉換或擴充形成的編碼,UTF是Unicode Translation Format的縮寫。
          ?
          [細節]
          關于ASCII編碼
          ????? ASCII編碼是美國標準信息交換碼,這種編碼方式針對的是英文字符。ASCII編碼使用一個字節對字符進行編碼,而且字節的最高位都為0,因此ASCII編碼的字符集大小是128個。由于英文字母僅有26個,再加上其他一些常用符號,總大小也不會超過128個,因此ASCII編碼的空間是足夠的。例如,字符“a”被編碼為0x61,字符“b”被編碼為0x62等等。注意,在有的時候ASCII泛指本地編碼,例如文本編輯器UltraEdit中有諸如“ASCII轉Unicode”的功能,這里的ASCII就泛指本地編碼,如果本地編碼是GBK,這個功能執行的就是GBK編碼到Unicode編碼的轉換。
          ?
          關于ISO8859-1編碼
          ????? ISO8859-1是西歐語系國家通用的字符集編碼,ISO8859-1使用一個字節對字符進行編碼,編碼值范圍是0x00-0xFF。其中,0x00-0x1F用作控制字,0x20-0x7F表示字母、數字和符號這些圖形字符,0xA0-0xFF作為附加部分使用。由于ASCII編碼只使用了一個字節中的低7位,編碼范圍僅為0-127,雖然可以容納英文字符和其他的一些符號,但是卻不能包含除英文以外的其他西歐語言的字母,因此ASCII編碼在西歐國家并不通用。針對這個問題ISO在ASCII編碼的基礎上進行了擴充,制定了ISO8859-1編碼,ISO8859-1編碼使用了一個字節的全部8位,編碼范圍是0-255,能包含西歐語系的所有字母和符號。
          ?
          關于GB2312、GBK和BIG5編碼
          ????? GB2312碼是中華人民共和國國家漢字信息交換使用碼,全稱《信息交換使用漢字編碼字符集-基本集》,由國家標準總局發布,1981年5月1日實施,中國大陸和新加坡等地使用此編碼。GB2312收錄了簡化漢字、符號、字母、日文假名等共計7445個字符,其中漢字占6763個。GB2312將代碼表分區94個區(0xA1-0xFE),對應第一個字節,每個區94個位(0xA1-0xFE),對應了第二字節,兩個字節的值分別為區號的值和位號的值加32(0x20),因此也被稱為區位碼。GB2312的編碼范7圍是0x2121-0x777E,與ASCII有重疊,通常方法是將GB碼的兩個字節的最高位置1區別。
          ????? GBK是GB2312-80的擴展,向上兼容,包含了20902個漢字,編碼范圍是0x8140-0xFEFE,剔除高位0x80的字位,其他字符都可以一一映射到Unicode2.0。GB18030-2000(GBK2K)在GBK的基礎上增加了藏、蒙等少數民族的字符,GBK2K從根本上解決了字位不夠、字形不足的問題。GBK2K首先要求實現能夠完全映射到Unicode3.0標準的所有字形,現在還沒有任何一個操作系統支持GBK2K。
          ??????BIG5碼被稱為大五碼,是中國港臺地區使用的字符編碼方式。TW-BIG5碼將所有字分為兩大群,即常用字區和次常用字區,每個字區分都采用筆畫排序,同筆畫的字依部首排序。TW-BIG5每個字由兩個字節組成,第一個字節編碼范圍是0xA1-0xF9,第二個字節編碼范圍是0x40-0x7E和0xA1-0xFE,共計收入13868個字,其中包括5401個常用字、7652個次常用字、7個擴充字、以及808個其他符號。
          ?
          關于Unicode編碼
          ????? ISO(國際化標準組織)將全世界所有的符號進行統一編碼,稱為Unicode編碼。Unicode編碼的字符占用兩個字符的大小,對于ASCII碼表示的字符,Unicode只是簡單的在ASCII碼原來的一個字節碼值上增加一個所有位全為0的字節。Unicode使用兩個字節編碼,因此能表示的字符集最大為65536,另外Unicode中還保留兩千多個數值未用于字符編碼。由于Unicode編碼的空間有限,只能包含各個地區常用的字符而非所有字符,因此,在相當長的一段時間里,本地化字符編碼和Unicode編碼將共存。
          ?
          關于UTF-8和UTF-16編碼
          ????? UTF-8和UTF-16編碼仍然屬于Unicode編碼,它們是在Unicode編碼基礎上進行了轉換或擴展。例如在Windows XP和2000操作系統中,Unicode編碼指的就是UTF-16編碼。
          ????? UTF-8編碼是將Unicode編碼中不同范圍的字符采用不同的字節進行編碼,對于ASCII編碼的字符仍使用一個字節進行編碼,UTF-8編碼完全兼容ASCII編碼。與Unicode想比較,UTF-8編碼使得英文文檔的占用空間減小了一半,因此UTF-8頗受英語系國家的青睞。除此之外,UTF-8編碼中不會出現值為0x0000的數據,這樣避免了和某些程序語言產生沖突,而UTF-8編碼的補充位使得數據能夠被方便的檢測出傳輸過程中是否發生錯誤。通常,UTF-8編碼都使用“EF BB BF”三個字節數據作為文件開頭。

          ????? Unicode編碼和UTF-8編碼結構的對應關系如下:
          ??????? Unicode編碼值???????????????????????? UTF-8編碼結構
          ????? ? \u0001 - \u007E??????????????????????0XXXXXXX
          ????? ? \u0080 - \u07FF 和 \u0000???????110XXXXX 10XXXXXX
          ??????? \u0800 - \uFFFF??????????????????????1110XXXX 10XXXXXX 10XXXXXX
          ?
          ????? Unicode編碼與UTF-8編碼的轉換如下(U8代表UTF-8編碼,U代表Unicode編碼):
          ????? 1) 位于Unicode編碼空間 \u0001-\u007F之間的字符(即編碼使用位小于8位的字符),UTF-8采用一個字節對這些字符進行編碼。直接將Unicode編碼的低位取出就得到了UTF-8編碼。轉換過程可表示為:U8 = (byte)U。
          ????? 2) 位于Unicode編碼空間\u0080-\u07FF之間的字符以及\u0000表示的字符(即編碼使用位為8-11位的字符,以及空字符),UTF-8采用兩個字節對這些字符進行編碼。這時候,將Unicode編碼轉換為UTF-8編碼的方法是:將Unicode編碼的低6位取出,在前面補充“10”作為低字節;將7-11位取出,在前面補充“110”作為高字節。轉換過程可表示為:U8 = [(byte)(0xC0 | (0x01F & (U>>6)),(byte)(0x80 | (0x3F & U)]。
          ????? 3) 位于Unicode編碼空間\u080-\uFFFF之間的字符(即編碼使用位為12-16位的字符),UTF-8采用三個字節對這些字符進行編碼。這時候,將Unicode編碼轉換為UTF-8編碼的方法是:將Unicode編碼的低6位取出,在前面補充“10”作為低字節;將7-12位取出,在前面補充“10”作為中字節;將13-16位取出,在前面補充“1110”作為高字節。轉換過程可表示為:U8 = [(byte)(0xE0 | (0x0F & (U>>12))),(byte)(0x80 | (0x03F & (U>>6)),(byte)(0x80 | (0x3F & U)]。
          ?
          ????? UTF-16編碼在Unicode基礎上進行了一些細節上的擴充,增加了對Unicode編碼沒有包括的字符的表示方式。UTF-16對Unicode的擴充并沒有影響Unicode編碼中的原有字符,容易看出Unicode是UTF-16的子集。Unicode編碼將0xD800-0xDFFF區間的數值保留,被稱為代理區間,區間共包含2048個數值,其中0xD800-0xD6FF是高半代理區,0xDC00-0xDFFF是低半代理區。UTF-16編碼就是在Unicode編碼基礎上利用代理區擴充字符編碼的機制。UTF-16編碼從兩個區域分別取一個編碼,組成一個4字節的代理對來表示一個編碼字符,就能夠在Unicode基礎上擴充了1024*1024個字符。UTF-16足夠用來編碼全球的所有字符,微軟從Windows2000開始支持UTF-16編碼。
          ?
          關于Little-Endian和Big-Endian
          ????? 在不同體系的計算機系統中,編碼的Unicode字符在內存中存儲的順序是不同的。使用Inter生產的CPU的計算機,內存中數據存儲通常是低字節在前,高字節在后,這種存儲方式被稱為Little-Endian。在對于一些計算機,內存中數據存儲通常是高字節在前,低字節在后,這種存儲方式被稱為Big-Endian。
          ????? UTF-16編碼的文件通常在文件開頭用字符標志出使用的存儲方式:若文件開頭是“0xFF 0xFF”,表示文件其余部分是Little-Endian的 UTF-16編碼;若文件開頭是“0xFE 0xFF”,表示文件其余部分是Big-Endian的 UTF-16編碼。

          posted @ 2006-09-28 11:36 xyang 閱讀(659) | 評論 (0)編輯 收藏

          [概述]
          ????? 在Windows操作系統中使用記事本新建一個文本文件,在文件里面寫入“聯通”兩個字并保存。當再次打開這個文本文件時候,在記事本中看到得卻不是剛剛輸入的“聯通”,而是亂碼。網絡上有人把這個奇怪現象包裝成把戲,如果你曾遇到過這種把戲就會知道,他們往往讓你建立兩個文本文件進行對比,其中一個輸入“聯通”,另外一個可能是“移動”等等,最后試圖八卦地讓你相信聯通、移動和微軟之間有著種種恩怨情仇。

          [解釋]
          ????? 這是一個字符編碼應用的奇怪現象,講的明白點,可以說是記事本開小差了!記事本為什么會犯錯誤?記事本犯了怎樣的錯誤呢?也許你會迫不及待的想知道這些問題,如果是這樣,我不會讓你空腹而歸的。
          ????? 在簡體中文操作系統中默認的本地字符集編碼是GBK編碼,除非你在保存記事本文本文件時候選擇了其他編碼方式,否則用記事本錄入的字符信息將使用GBK編碼進行儲存。巧合的是,“聯通”這兩個字符的GBK編碼具有UTF-8編碼的特征,記事本犯下的錯誤正是將GBK編碼存放的記錄有“聯通”兩個字符的文件誤認為UTF-8編碼的文件。或許你會問,UTF-8編碼的文件不是以“EF BB BF”三個特殊字節開頭嗎?既然這樣,記事本怎么會犯這么低級的錯誤呢?沒錯,UTF-8編碼規定使用UTF-8編碼的文件以“EF BB BF”三個特殊字節開頭,但并不是強制性要求,早期的UTF-8編碼文件就不遵循這個規定。因此記事本不能依靠文件的開頭字節判斷一個文件是否是UTF-8編碼,而只能對文件中的數據進行簡單的編碼分析來確定。正是這個原因,才有了字符編碼應用中的這個奇怪又無法避免的現象。

          [細節]
          ????? 如果上面的解釋對于你來說只是杯開胃紅酒,那我還是塊點把主食呈上吧,一份大峽谷香烤豬肋排。UTF-8編碼采用1-3個字節對字符進行編碼,編碼字節數與字符的Unicode編碼值有嚴格的對應關系,讓我們回憶下UTF-8編碼和Unicode的對應關系吧。

          ????? Unicode編碼值???????????????????????????? ?UTF-8編碼結構
          ????? \u0001 - \u007E?????????????????????????? 0XXXXXXX
          ????? \u0080 - \u07FF 和 \u0000?????????? ?110XXXXX 10XXXXXX
          ????? \u0800 - \uFFFF??????????????????????????? 1110XXXX 10XXXXXX 10XXXXXX

          ????? “聯通”這兩個字符的GBK編碼值是“C1 AA CD A8",GBK編碼方式使用兩個字節對一個字符進行編碼,因此以GBK編碼方式存放的錄有“聯通”兩個字符的文件的大小為四個字節。接下來分別觀察“聯通”這兩個字符GBK編碼值的二進制形式,你有發現有趣的事。

          ????? 聯??? GBK??? 十六進制:C1 AA??? 二進制:1100 0001,1010 1010
          ????? 通??? GBK??? 十六進制:C1 AA??? 二進制:1100 1101,1010 1000

          ????? 請注意上面二進制數據的著色部分,你想到了什么?對,它們和UTF-8編碼結構中的補充位完全一致,UTF-8編碼的補充位使得編碼值更有規律,而記事本剛好憑借這個特征區分UTF-8編碼的文件。存有“聯通”兩個字符的文件的所有數據都符合這個特征,就是這樣,記事本徹底的將文件誤認為UTF-8編碼的文件。
          ????? 將錯就錯,讓我們來看看這個錯誤是怎樣收場的。如果把“聯通”的GBK編碼值當作UTF-8編碼值,那文件就成為一個寫有數據“C1 AA CD A8”并以UTF-8編碼的文件,當使用記事本再次打開的時候會看到什么呢?只要將UTF-8編碼轉換成Unicode編碼就知道了。UTF-8編碼“C1 AA CD A8”轉換成Unicode編碼后,編碼值為“6A 00 68 03”(轉換方法請參考本Blog中的《字符編碼》一文)。0x006A這個Unicode編碼值位于\u0001 - \u007E之間,若要轉換為UTF-8編碼,顯然只能用一個字節進行編碼,因此“聯”的GBK編碼“C1 AA”雖然特征上貌似UTF-8編碼,但它卻不對應任何一個UTF-8編碼。接著看0x0368這個Unicode編碼值,這個值對應了字符“?”,這也正是我們將在記事本中看到的內容。或許你會說我看到的是一個黑色矩形啊,這只是字體的原因,你將字體改為宋體或者其他字體,看到的就是字符“?”。
          ????? 對于中文字符,UTF-8編碼要用三個字節進行編碼,因此,如果你使用記事本錄入“聯通”,然后選擇以UTF-8編碼方式保存的話,文件大小應為9個字節(包含三個字節的開頭數據),而同樣的文件GBK編碼卻是4個字節。最后附上“聯通”的GBK、UTF-8、Unicode編碼值,以及記事本的錯誤思維。

          ????? 聯通??GBK? C1 AA CD A8??? UTF-8? E8 81 94 E9 80 9A??? Unicode? 54 80 1A 90
          ????? 聯通? GBK? C1 AA CD A8??? UTF-8? C1 AA CD A8????????????Unicode? 6A 00 68 03? (將GBK值誤認為UTF-8值的結果)

          posted @ 2006-09-28 11:36 xyang 閱讀(297) | 評論 (0)編輯 收藏

          [概述]
          ????? 在編程中字符編碼絕對是個值得重視的問題,當讀取一個文件或是得到一個輸入流,你需要分析數據的編碼方式、形態,以便能正確的處理、顯示數據所表示的字符。

          [細節]
          ????? 1)? 在簡體中文操作系統中,從鍵盤輸入的原始字符采用的是GBK編碼方式,對應到其他操作系統,采用的應是系統默認的本地字符集。而在程序設計語言中,字符和字符串則通常是使用Unicode編碼方式,這一點可以用下列代碼說明(使用Java語言描述)。

          ????? int ch = System.in.read(); //從鍵盤輸入中讀取一個字節的數據
          ????? 如果輸入“中國”兩個字符,使用上面的代碼將所有的數據讀取,將得到“D6 D0 B9 FA”,這寫數據正是“中國”兩個字符的GBK編碼值。
          ????? String tmp = "中國"; //定義字符串并賦值
          ????? for(int i=0;i<tmp.length();i++)
          ????? {
          ????? //將字符串中的每個字符編碼值以十六進制形式顯示
          ???????? System.out.println(Integer.toHexString(ch));
          ????? }

          ????? 上面代碼最后顯示的內容是“4E2D 56FD”,而這正是“中國”兩個字符的Unicode編碼值。
          ?
          ????? 2) 不僅是輸入的原始字符采用GBK編碼,屏幕輸出的最終數據也要采用GBK編碼,下面的代碼能說明問題。

          ????? String tmp = "中國"; //定義字符串并賦值
          ????? System.out.println(tmp); //將字符串tmp輸出到顯示屏

          ????? 代碼運行后,在顯示屏上顯然能看到“中國”兩個字符,而字符串tmp分明是采用Unicode進行編碼的,是不是剛才提出的命題站不住腳呢?其實,在調用println()方法后,該方法自動的將字符串tmp的編碼方式從Unicode轉換成了本地編碼GBK,這樣才能在屏幕上正常的顯示中文。如果你仍然懷疑,請繼續往下看。

          ????? byte [] buf1 = tmp.getBytes("Unicode"); //將字符串tmp以Unicode編碼方式儲存在字節數組中
          ????? byte [] buf2 = tmp.getBytes("GB2312"); //將字符串tmp以UGBK編碼方式儲存在字節數組中
          ????? //在屏幕輸出流中直接寫字節數組
          ????? System.out.write(buf1);
          ????? System.out.write(buf2);

          ????? 這樣的作法將會得到什么結果呢?結果也許會令你感到驚訝,buf1的數據輸出后顯示為亂碼,而buf2的數據輸出后赫然顯示為“中國”兩個字符。可以把命題說得明確點:如果要在屏幕上輸出漢字,那么字符的最終編碼方式必須是GBK編碼方式。對于數字和英文字母,以及ASCII編碼集中包含的符號,字符的最終編碼方式可以是ASCII,這種情況下如果使用Unicode編碼,那么顯示的結果會是這樣“1 2 3 a b c ”,本來想顯示的內容是“123abc”。顯示結果字符間多了個貌似空格的字符,這是因為ASCII編碼使用一個字節,Unicode編碼使用兩個字節,在ASCII編碼轉換為Unicode時候,只是單純地在編碼值前面補充一個全為0的字節,這個字節在最終顯示的時候被看做是空字符NUL。
          ?
          ????? 3) 在涉及網頁、網絡流和關系數據庫方面編程的時候,字符編碼總喜歡戲弄編程人員,不花心思去馴服它的結果將是得到一堆亂碼。例如在讀取數據數據時候,數據庫中的內容是中文字符,如果數據庫沒有考慮到中文支持問題就很容易得到亂碼。再例如程序運行的平臺默認編碼并非GBK,在獲取GBK編碼的字符數據時候,程序會將數據看作默認編碼,這樣也容易產生亂碼。在上述情況中編寫程序的時候,就應該耐心的分析數據的編碼方式,合理的編寫代碼防止亂碼。
          ?
          [例子]???
          ????? 記得在《Java手機程序設計入門與應用》(王森 編著)一書的第13章-MIDP網絡程序設計中有一段使用HTTP進行網絡連接的實例代碼,部分代碼如下所示。

          ????? String url = " http://127.0.0.1/test.html ";
          ????? HttpConnection hc = (HttpConnection)Connector.open(url);
          ????? DataInputStream dis = new DataInputStream(hc.openInputStream());
          ????? String content = "";
          ????? int ic;
          ????? while((ic = dis.read()) != -1)
          ????? {
          ????????? content += (char)ic;
          ????? }
          ????? Form f = new Form("HTTP Test");
          ????? f.append(content);
          ????? Display.getDisplay(this).setCurrent(f);

          ????? 這段代碼讓手機通過HTTP協議與網絡中的主機進行通信,然后獲得網絡主機上的文件test.html并將文件內容讀取到字符串變量中,最后顯示到程序窗體中。如果程序這般執行的話,你會發現MIDlet顯示出來中文都是亂碼。作者稱“之所以會有這種結果,原因在于我們的仿真器支持Unicode的緣故。”,作者的意思似乎是MIDlet將本地編碼的字符數據誤認為了Unicode編碼的數據,因此不能正常顯示,然后推薦了一種解決方法:使用ASCII形態的Unicode。
          ????? 所謂ASCII形態的Unicode指的是使用ASCII編碼的字符來表示Unicode編碼值,反過來說就是將Unicode的編碼值看做字符,再用ASCII對這些字符進行編碼存放。比如“中國”這兩個字符的ASCII形態的Unicode編碼字符為“\u4e2d\u56fd”,0x4E2D 0x56FD 分別為“中”和“國”的Unicode編碼值,將編碼值作為字符,然后在前面添加“\u”標識符,以便進行還原。再對這些字符進行ASCII編碼就得到了ASCII形態的Unicode編碼值,最終的值為“5C 75 34 65 32 64 5C 75 35 36 66 64”,一共12個字節的數據,分別對應了“\u4e2d\u56fd”中的一個字符。使用jdk*\bin文件夾下的native2ascii.exe程序可以很方便的將一個文件轉換為ASCII形態的Unicode編碼。將文件test.html轉換形態后,MIDlet中需要再次將ASCII形態的Unicode轉換為Unicode編碼,這個轉換方法需要自己寫,最后MIDlet中顯示出來的就是正常的中文字符。

          ????? 在我看來,那本書的作者沒有把握住問題的真正原因,也或許是我們使用的模擬器和平臺不同。如果把握住真正的原因,問題的解決方法就變得很簡單了。前面說過,要在屏幕上顯示出中文,字符的最終編碼形式必須是GBK,在中國大陸發現的手機都能顯示中文,也就說明手機中都支持GBK編碼。那為什么會出現中文字符亂碼的問題呢?我的理由是手機中采用的默認編碼是ISO8859-1,對于從網絡中讀入的字符數據,在沒有指明的情況下,MIDlet一律將它們看作是ISO8859-1編碼的數據。而test.html的編碼方式是GBK,MIDlet犯了個錯誤,它將GBK編碼的數據誤認為了ISO8859-1編碼的數據,然后在顯示的時候又進行了一次ISO8859-1到GBK的編碼轉換,這樣的結果是數據遭到了破壞,顯示出來的中文也就變成了亂碼。
          ????? 把握住了原因,解決起來就十分方便了。既然MIDlet將GBK編碼的數據誤認為ISO8859-1編碼的數據,那么我們只要在程序中指明數據的編碼方式就可以了,而不用使用“ASCII形態的Unicode”這樣的舍本求末的方法。下面是解決MIDlet網絡連接中文亂碼問題的代碼,這些代碼將證明我的觀點。

          ????? http://127.0.0.1/test.html;
          ????? HttpConnection hc = (HttpConnection)Connector.open(url);
          ??????byte [] buf = new byte[1024];
          ????? int len = hc.openInputStream().read(buf);? //讀取網絡數據
          ????? String content = new String(buf,0,len,"GB2312");? //指定數據為GBK編碼
          ??????Form f = new Form("HTTP Test");
          ????? f.append(content);?
          ????? display.setCurrent(f);

          ????? 上述代碼中關鍵的一句是:
          ????? String content = new String(buf,0,len,"GB2312");
          ????? 這句代碼告訴MIDlet從網絡中讀取的數據使用的是GBK編碼方式,然后MIDlet便能爭取處理和顯示這些數據。
          ????? 如果將這句代碼改寫為:?
          ????? String content = new String(buf,0,len);
          ????? 或者是:
          ??????String content = new String(buf,0,len,"ISO8859-1");
          ????? 都將出現同樣的中文亂碼現象,由此斷定錯誤的原因是手機默認編碼使用ISO8859-1,MIDlet將從網絡中讀取的GBK編碼的數據誤認成了ISO8859-1編碼的數據。

          posted @ 2006-09-28 11:35 xyang 閱讀(675) | 評論 (0)編輯 收藏

          Unicode編碼

          Unicode是一種字符編碼規范 。

          先從ASCII說起。ASCII是用來表示英文字符的一種編碼規范,每個ASCII字符占用1個字節(8bits)

          因此,ASCII編碼可以表示的最大字符數是256,其實英文字符并沒有那么多,一般只用前128個(最高位為0),其中包括了控制字符、數字、大小寫字母和其他一些符號 。

          而最高位為1的另128個字符被成為“擴展ASCII”,一般用來存放英文的制表符、部分音標字符等等的一些其他符號

          這種字符編碼規范顯然用來處理英文沒有什么問題 。(實際上也可以用來處理法文、德文等一些其他的西歐字符,但是不能和英文通用),但是面對中文、阿拉伯文之類復雜的文字,255個字符顯然不夠用

          于是,各個國家紛紛制定了自己的文字編碼規范,其中中文的文字編碼規范叫做“GB2312-80”,它是和ASCII兼容的一種編碼規范,其實就是利用擴展ASCII沒有真正標準化這一點,把一個中文字符用兩個擴展ASCII字符來表示。

          但是這個方法有問題,最大的問題就是,中文文字沒有真正屬于自己的編碼,因為擴展ASCII碼雖然沒有真正的標準化,但是PC里的ASCII碼還是有一個事實標準的(存放著英文制表符),所以很多軟件利用這些符號來畫表格。這樣的軟件用到中文系統中,這些表格符就會被誤認作中文字,破壞版面。而且,統計中英文混合字符串中的字數,也是比較復雜的,我們必須判斷一個ASCII碼是否擴展,以及它的下一個ASCII是否擴展,然后才“猜”那可能是一個中文字 。

          總之當時處理中文是很痛苦的。而更痛苦的是GB2312是國家標準,臺灣當時有一個Big5編碼標準,很多編碼和GB是相同的,所以……,嘿嘿。

          這時候,我們就知道,要真正解決中文問題,不能從擴展ASCII的角度入手,也不能僅靠中國一家來解決。而必須有一個全新的編碼系統,這個系統要可以將中文、英文、法文、德文……等等所有的文字統一起來考慮,為每個文字都分配一個單獨的編碼,這樣才不會有上面那種現象出現。

          于是,Unicode誕生了。

          Unicode有兩套標準,一套叫

          Unicode-16UCS-2,用2個字節為字符編碼,另一套叫Unicode-32UCS-4,用4個字節為字符編碼。

          以目前常用的

          Unicode-16UCS-2為例,它可以表示的字符數為2^16=65535,基本上可以容納所有的歐美字符和絕大部分的亞洲字符 。

          UTF-8的問題后面會提到 。

          在Unicode里,所有的字符被一視同仁。漢字不再使用“兩個擴展ASCII”,而是使用“1個Unicode”,注意,現在的漢字是“一個字符”了,于是,拆字、統計字數這些問題也就自然而然的解決了 。

          但是,這個世界不是理想的,不可能在一夜之間所有的系統都使用Unicode來處理字符,所以Unicode在誕生之日,就必須考慮一個嚴峻的問題:和ASCII字符集之間的不兼容問題。

          我們知道,ASCII字符是單個字節的,比如“A”的ASCII是65。而Unicode是雙字節的,比如“A”的Unicode是0065,這就造成了一個非常大的問題:以前處理ASCII的那套機制不能被用來處理Unicode了 。

          另一個更加嚴重的問題是,C語言使用'\0'作為字符串結尾,而Unicode里恰恰有很多字符都有一個字節為0,這樣一來,C語言的字符串函數將無法正常處理Unicode,除非把世界上所有用C寫的程序以及他們所用的函數庫全部換掉 。

          于是,比Unicode更偉大的東東誕生了,之所以說它更偉大是因為它讓Unicode不再存在于紙上,而是真實的存在于我們大家的電腦中。那就是:UTF 。

          UTF= UCS Transformation Format UCS轉換格式

          它是將Unicode編碼規則和計算機的實際編碼對應起來的一個規則。現在流行的UTF有2種:UTF-8和UTF-16 。

          其中UTF-16和上面提到的Unicode本身的編碼規范是一致的,這里不多說了。而UTF-8不同,它定義了一種“區間規則”,這種規則可以和ASCII編碼保持最大程度的兼容 。

          UTF-8有點類似于Haffman編碼,它將Unicode編碼為00000000-0000007F的字符,用單個字節來表示;

          00000080-000007FF的字符用兩個字節表示

          00000800-0000FFFF的字符用3字節表示

          因為目前為止Unicode-16規范沒有指定FFFF以上的字符,所以UTF-8最多是使用3個字節來表示一個字符。但理論上來說,UTF-8最多需要用6字節表示一個字符。

          在UTF-8里,英文字符仍然跟ASCII編碼一樣,因此原先的函數庫可以繼續使用。而中文的編碼范圍是在0080-07FF之間,因此是2個字節表示(但這兩個字節和GB編碼的兩個字節是不同的),用專門的Unicode處理類可以對UTF編碼進行處理。

          下面說說中文的問題。

          由于歷史的原因,在Unicode之前,一共存在過3套中文編碼標準。

          GB2312-80,是中國大陸使用的國家標準,其中一共編碼了6763個常用簡體漢字。Big5,是臺灣使用的編碼標準,編碼了臺灣使用的繁體漢字,大概有8千多個。HKSCS,是中國香港使用的編碼標準,字體也是繁體,但跟Big5有所不同。

          這3套編碼標準都采用了兩個擴展ASCII的方法,因此,幾套編碼互不兼容,而且編碼區間也各有不同

          因為其不兼容性,在同一個系統中同時顯示GB和Big5基本上是不可能的。當時的南極星、RichWin等等軟件,在自動識別中文編碼、自動顯示正確編碼方面都做了很多努力 。

          他們用了怎樣的技術我就不得而知了,我知道好像南極星曾經以同屏顯示繁簡中文為賣點。

          后來,由于各方面的原因,國際上又制定了針對中文的統一字符集GBK和GB18030,其中GBK已經在Windows、Linux等多種操作系統中被實現。

          GBK兼容GB2312,并增加了大量不常用漢字,還加入了幾乎所有的Big5中的繁體漢字。但是GBK中的繁體漢字和Big5中的幾乎不兼容。

          GB18030相當于是GBK的超集,比GBK包含的字符更多。據我所知目前還沒有操作系統直接支持GB18030。

          這是一篇程序員寫給程序員的趣味讀物。所謂趣味是指可以比較輕松地了解一些原來不清楚的概念,增進知識,類似于打RPG游戲的升級。整理這篇文章的動機是兩個問題:


          問題一:
          使用Windows記事本的“另存為”,可以在GBK、Unicode、Unicode big endian和UTF-8這幾種編碼方式間相互轉換。同樣是txt文件,Windows是怎樣識別編碼方式的呢?

          我很早前就發現Unicode、Unicode big endian和UTF-8編碼的txt文件的開頭會多出幾個字節,分別是FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)。但這些標記是基于什么標準呢?

          問題二:
          最近在網上看到一個ConvertUTF.c,實現了UTF-32、UTF-16和UTF-8這三種編碼方式的相互轉換。對于Unicode(UCS2)、GBK、UTF-8這些編碼方式,我原來就了解。但這個程序讓我有些糊涂,想不起來UTF-16和UCS2有什么關系。
          查了查相關資料,總算將這些問題弄清楚了,順帶也了解了一些Unicode的細節。寫成一篇文章,送給有過類似疑問的朋友。本文在寫作時盡量做到通俗易懂,但要求讀者知道什么是字節,什么是十六進制。

          0、big endian和little endian
          big endian和little endian是CPU處理多字節數的不同方式。例如“漢”字的Unicode編碼是6C49。那么寫到文件里時,究竟是將6C寫在前面,還是將49寫在前面?如果將6C寫在前面,就是big endian。還是將49寫在前面,就是little endian。

          “endian”這個詞出自《格列佛游記》。小人國的內戰就源于吃雞蛋時是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開,由此曾發生過六次叛亂,其中一個皇帝送了命,另一個丟了王位。

          我們一般將endian翻譯成“字節序”,將big endian和little endian稱作“大尾”和“小尾”。

          1、字符編碼、內碼,順帶介紹漢字編碼
          字符必須編碼后才能被計算機處理。計算機使用的缺省編碼方式就是計算機的內碼。早期的計算機使用7位的ASCII編碼,為了處理漢字,程序員設計了用于簡體中文的GB2312和用于繁體中文的big5。

          GB2312(1980年)一共收錄了7445個字符,包括6763個漢字和682個其它符號。漢字區的內碼范圍高字節從B0-F7,低字節從A1-FE,占用的碼位是72*94=6768。其中有5個空位是D7FA-D7FE。

          GB2312支持的漢字太少。1995年的漢字擴展規范GBK1.0收錄了21886個符號,它分為漢字區和圖形符號區。漢字區包括21003個字符。2000年的GB18030是取代GBK1.0的正式國家標準。該標準收錄了27484個漢字,同時還收錄了藏文、蒙文、維吾爾文等主要的少數民族文字。現在的PC平臺必須支持GB18030,對嵌入式產品暫不作要求。所以手機、MP3一般只支持GB2312。

          從ASCII、GB2312、GBK到GB18030,這些編碼方法是向下兼容的,即同一個字符在這些方案中總是有相同的編碼,后面的標準支持更多的字符。在這些編碼中,英文和中文可以統一地處理。區分中文編碼的方法是高字節的最高位不為0。按照程序員的稱呼,GB2312、GBK到GB18030都屬于雙字節字符集 (DBCS)。

          有的中文Windows的缺省內碼還是GBK,可以通過GB18030升級包升級到GB18030。不過GB18030相對GBK增加的字符,普通人是很難用到的,通常我們還是用GBK指代中文Windows內碼。

          這里還有一些細節:

          GB2312的原文還是區位碼,從區位碼到內碼,需要在高字節和低字節上分別加上A0。

          在DBCS中,GB內碼的存儲格式始終是big endian,即高位在前。

          GB2312的兩個字節的最高位都是1。但符合這個條件的碼位只有128*128=16384個。所以GBK和GB18030的低字節最高位都可能不是1。不過這不影響DBCS字符流的解析:在讀取DBCS字符流時,只要遇到高位為1的字節,就可以將下兩個字節作為一個雙字節編碼,而不用管低字節的高位是什么。

          2、Unicode、UCS和UTF
          前面提到從ASCII、GB2312、GBK到GB18030的編碼方法是向下兼容的。而Unicode只與ASCII兼容(更準確地說,是與ISO-8859-1兼容),與GB碼不兼容。例如“漢”字的Unicode編碼是6C49,而GB碼是BABA。

          Unicode也是一種字符編碼方法,不過它是由國際組織設計,可以容納全世界所有語言文字的編碼方案。Unicode的學名是"Universal Multiple-Octet Coded Character Set",簡稱為UCS。UCS可以看作是"Unicode Character Set"的縮寫。

          根據維基百科全書( http://zh.wikipedia.org/wiki/ )的記載:歷史上存在兩個試圖獨立設計Unicode的組織,即國際標準化組織(ISO)和一個軟件制造商的協會(unicode.org)。ISO開發了ISO 10646項目,Unicode協會開發了Unicode項目。

          在1991年前后,雙方都認識到世界不需要兩個不兼容的字符集。于是它們開始合并雙方的工作成果,并為創立一個單一編碼表而協同工作。從Unicode2.0開始,Unicode項目采用了與ISO 10646-1相同的字庫和字碼。

          目前兩個項目仍都存在,并獨立地公布各自的標準。Unicode協會現在的最新版本是2005年的Unicode 4.1.0。ISO的最新標準是10646-3:2003。

          UCS規定了怎么用多個字節表示各種文字。怎樣傳輸這些編碼,是由UTF(UCS Transformation Format)規范規定的,常見的UTF規范包括UTF-8、UTF-7、UTF-16。

          IETF的RFC2781和RFC3629以RFC的一貫風格,清晰、明快又不失嚴謹地描述了UTF-16和UTF-8的編碼方法。我總是記不得IETF是Internet Engineering Task Force的縮寫。但IETF負責維護的RFC是Internet上一切規范的基礎。

          3、UCS-2、UCS-4、BMP

          UCS有兩種格式:UCS-2和UCS-4。顧名思義,UCS-2就是用兩個字節編碼,UCS-4就是用4個字節(實際上只用了31位,最高位必須為0)編碼。下面讓我們做一些簡單的數學游戲:

          UCS-2有2^16=65536個碼位,UCS-4有2^31=2147483648個碼位。

          UCS-4根據最高位為0的最高字節分成2^7=128個group。每個group再根據次高字節分為256個plane。每個plane根據第3個字節分為256行 (rows),每行包含256個cells。當然同一行的cells只是最后一個字節不同,其余都相同。

          group 0的plane 0被稱作Basic Multilingual Plane, 即BMP。或者說UCS-4中,高兩個字節為0的碼位被稱作BMP。

          將UCS-4的BMP去掉前面的兩個零字節就得到了UCS-2。在UCS-2的兩個字節前加上兩個零字節,就得到了UCS-4的BMP。而目前的UCS-4規范中還沒有任何字符被分配在BMP之外。

          4、UTF編碼

          UTF-8就是以8位為單元對UCS進行編碼。從UCS-2到UTF-8的編碼方式如下:

          UCS-2編碼(16進制) UTF-8 字節流(二進制)
          0000 - 007F 0xxxxxxx
          0080 - 07FF 110xxxxx 10xxxxxx
          0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx

          例如“漢”字的Unicode編碼是6C49。6C49在0800-FFFF之間,所以肯定要用3字節模板了:1110xxxx 10xxxxxx 10xxxxxx。將6C49寫成二進制是:0110 110001 001001, 用這個比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。

          讀者可以用記事本測試一下我們的編碼是否正確。

          UTF-16以16位為單元對UCS進行編碼。對于小于0x10000的UCS碼,UTF-16編碼就等于UCS碼對應的16位無符號整數。對于不小于0x10000的UCS碼,定義了一個算法。不過由于實際使用的UCS2,或者UCS4的BMP必然小于0x10000,所以就目前而言,可以認為UTF-16和UCS-2基本相同。但UCS-2只是一個編碼方案,UTF-16卻要用于實際的傳輸,所以就不得不考慮字節序的問題。

          5、UTF的字節序和BOM
          UTF-8以字節為編碼單元,沒有字節序的問題。UTF-16以兩個字節為編碼單元,在解釋一個UTF-16文本前,首先要弄清楚每個編碼單元的字節序。例如收到一個“奎”的Unicode編碼是594E,“乙”的Unicode編碼是4E59。如果我們收到UTF-16字節流“594E”,那么這是“奎”還是“乙”?

          Unicode規范中推薦的標記字節順序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一個有點小聰明的想法:

          在UCS編碼中有一個叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的編碼是FEFF。而FFFE在UCS中是不存在的字符,所以不應該出現在實際傳輸中。UCS規范建議我們在傳輸字節流前,先傳輸字符"ZERO WIDTH NO-BREAK SPACE"。

          這樣如果接收者收到FEFF,就表明這個字節流是Big-Endian的;如果收到FFFE,就表明這個字節流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被稱作BOM。

          UTF-8不需要BOM來表明字節順序,但可以用BOM來表明編碼方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF(讀者可以用我們前面介紹的編碼方法驗證一下)。所以如果接收者收到以EF BB BF開頭的字節流,就知道這是UTF-8編碼了。

          Windows就是使用BOM來標記文本文件的編碼方式的。

          6、進一步的參考資料
          本文主要參考的資料是 "Short overview of ISO-IEC 10646 and Unicode" (
          http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html )。

          我還找了兩篇看上去不錯的資料,不過因為我開始的疑問都找到了答案,所以就沒有看:

          "Understanding Unicode A general introduction to the Unicode Standard" ( http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter04a )
          "Character set encoding basics Understanding character set encodings and legacy encodings" (
          http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter03 )

          posted @ 2006-09-28 11:06 xyang 閱讀(213) | 評論 (0)編輯 收藏

          ??? ie默認根據服務器傳回來的contentType頭進行顯示(忽略mata標簽),對于html這種靜態文件,由于沒有contentType頭則根據<meta http-equiv="Content-Type" content="text/html; charset=GBK" />標簽中的編碼類型進行顯示.

          ??? pageEncoding指定的是jsp編譯時的編碼格式,必須對應于jsp文件內容的編碼,否則是亂碼
          默認pageEncoding為:ISO-8859-1,如果不指定contentType,輸出對應于pageEncoding的編碼方式
          也就是如果都不設置的話,默認輸出ISO-8859-1,肯定是亂碼(保存為unicode即可正常顯示).

          ??? response.setCharacterEncoding("GBK")
          <%@ page contentType="text/html; charset=UTF-8">
          這兩句作用相同,設置輸出的編碼類型,但response.setCharacterEncoding("GBK")優先級高

          ??? 通過 get/post 方式從 ie中發送漢字,發送編碼方式由Content-Type決定,request.getParameter("XX")得到的字符串是用ISO-8859-1表示的,所以必須在取值前用HttpServeletRequest.setCharacterEncoding 設置想得到的編碼類型,或是在<Connector>中添加URIEncoding="GBK"屬性,來獲取正確的編碼類型,但是,在執行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()自然就無效。



          <% @?page?contentType = " text/html;?charset=UTF-8 " ?pageEncoding = " UTF-8 " %>
          <%
          request.setCharacterEncoding(
          " UTF-8 " );
          response.setCharacterEncoding(
          " UTF-8 " );
          %>
          < html >
          ??
          < head >
          ????
          < title > test </ title >
          ????
          < meta? http-equiv ="Content-Type" ?content ="text/html;?charset=UTF-8" ? />
          ??
          </ head >
          ??
          < body > = <% = new ? String (request.getParameter( " foo " ).getBytes( " iso8859-1 " ), " UTF-8 " ) %> =
          ??????
          < form? action ="" ?method ="get" >
          ??????foo?=?
          < input? type ="text" ?name ="foo" ?value ="${param[" foo"]}" >
          ??????????
          < input? type ="submit" >
          ??????
          </ form >
          ??????tomcat:
          < Connector? port ="8080" ?URIEncoding ="GBK" ? />
          ??
          </ body >
          </ html >

          posted @ 2006-09-28 09:47 xyang 閱讀(377) | 評論 (0)編輯 收藏

          作者:owen1944

          一、字節和unicode

          Java內核是unicode的,就連class文件也是,但是很多媒體,包括文件/流的保存方式是使用字節流的。因此Java要對這些字節流經行轉化。char是unicode的,而byte是字節。Java中byte/char互轉的函數在sun.io的包中間有。其中ByteToCharConverter類是中調度,可以用來告訴你,你用的convertor。其中兩個很常用的靜態函數是:

          ?

          public static ByteToCharConverter getDefault();
          public static ByteToCharConverter getConverter(String encoding);

          ?

          如果你不指定converter,則系統會自動使用當前的encoding,gb平臺上用gbk,en平臺上用8859_1。


          byte ——〉char:
          "你"的gb碼是:0xc4e3 ,unicode是0x4f60
          String encoding = "gb2312";
          byte b[] = {(byte)'\u00c4',(byte)'\u00e3'};
          ByteToCharConverter converter = ByteToCharConverter.getConverter(encoding);
          char c[] = converter.convertAll(b);
          for (int i = 0; i < c.length; i++) {
          System.out.println(Integer.toHexString(c[i]));
          }
          結果是什么?0x4f60
          如果encoding ="8859_1",結果又是什么?0x00c4,0x00e3

          ?

          如果代碼改為:


          byte b[] = {(byte)'\u00c4',(byte)'\u00e3'};
          ByteToCharConverter converter = ByteToCharConverter. getDefault();
          ?char c[] = converter.convertAll(b);
          ?for (int i = 0; i < c.length; i++) {
          ??? System.out.println(Integer.toHexString(c[i]));
          ?}

          ?

          結果將又是什么?

          這就要根據平臺的編碼而定。


          char ——〉byte:
          ??? String encoding = "gb2312";
          ??? char c[] = {'\u4f60'};
          ??? CharToByteConverter converter = CharToByteConverter.getConverter(encoding);
          ??? byte b[] = converter.convertAll(c);
          ??? for (int i = 0; i < b.length; i++) {
          ?????? System.out.println(Integer.toHexString(b[i]));
          ??? }
          結果是什么?0x00c4,0x00e3
          如果encoding ="8859_1",結果又是什么?0x3f
          如果代碼改為
          String encoding = "gb2312";
          ??? char c[] = {'\u4f60'};
          ??? CharToByteConverter converter = CharToByteConverter.getDefault();
          ??? byte b[] = converter.convertAll(c);
          ??? for (int i = 0; i < b.length; i++) {
          ?????? System.out.println(Integer.toHexString(b[i]));
          ??? }

          ?

          結果將又是什么?還是根據平臺的編碼而定。

          很多中文問題就是從這兩個最簡單的類派生出來的。而卻有很多類不直接支持把encoding輸入,這給我們帶來諸多不便。很多程序難得用encoding了,直接用default的encoding,這就給我們移植帶來了很多困難。

          二、utf-8

          utf-8是和unicode一一對應的,其實現很簡單:


          7位的unicode: 0 _ _ _ _ _ _ _
          11位的unicode: 1 1 0 _ _ _ _ _ 1 0 _ _ _ _ _ _
          16位的unicode: 1 1 1 0 _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _
          21位的unicode: 1 1 1 1 0 _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _

          ?

          大多數情況是只使用到16位以下的unicode:


          "你"的gb碼是:0xc4e3 ,unicode是0x4f60
          ??? 0xc4e3的二進制:
          ????????? 1100 ,0100 ,1110 ,0011

          ?

          由于只有兩位我們按照兩位的編碼來排,但是我們發現這行不通,因為第7位不是0因此,返回"?"


          0x4f60的二進制:
          ?????????????? 0100 ,1111 ,0110 ,0000
          ???????? 我們用utf-8補齊,變成:
          ?????????????? 1110 ,0100 ,1011 ,1101 ,1010 ,0000
          ???????? e4--bd-- a0
          ???????? 于是返回:0xe4,0xbd,0xa0。

          ?

          三、string和byte[]

          string其實核心是char[],然而要把byte轉化成string,必須經過編碼。string.length()其實就是char數組的長度,如果使用不同的編碼,很可能會錯分,造成散字和亂碼。例如:


          String encoding = “”;
          byte [] b={(byte)'\u00c4',(byte)'\u00e3'};
          String str=new String(b,encoding);

          ?

          如果encoding=8859_1,會有兩個字,但是encoding=gb2312只有一個字這個問題在處理分頁是經常發生。

          四、Reader,Writer / InputStream,OutputStream

          Reader和Writer核心是char,InputStream和OutputStream核心是byte。但是Reader和Writer的主要目的是要把char讀/寫InputStream/OutputStream。例如:


          文件test.txt只有一個"你"字,0xc4,0xe3
          String encoding = "gb2312";
          ??? InputStreamReader reader = new InputStreamReader(new FileInputStream(
          ??????? "text.txt"), encoding);
          ??? char c[] = new char[10];
          ??? int length = reader.read(c);
          ??? for (int i = 0; i < length; i++) {
          ?????? System.out.println(c[i]);
          ??? }

          ?

          結果是什么?是"你"。如果encoding ="8859_1",結果是什么?"??"兩個字符,表示不認識。反過來的例子自己做。
          五、我們要對Java的編譯器有所了解:

          ?

          ?

          ?

          ?

          ?

          ?

          Javac ?encoding

          ?

          我們常常沒有用到encoding這個參數。其實encoding這個參數對于跨平臺的操作是很重要的。如果沒有指定encoding,則按照系統的默認encoding,gb平臺上是gb2312,英文平臺上是iso8859_1。Java的編譯器實際上是調用sun.tools.Javac.main的類,對文件進行編譯,這個類有compile函數中間有一個encoding的變量,-encoding的參數其實直接傳給encoding變量。編譯器就是根據這個變量來讀取Java文件的,然后把用utf-8形式編譯成class文件。例子代碼:


          String str = "你";
          ??? FileWriter writer = new FileWriter("text.txt");
          ??? write.write(str);
          ??? writer.close();

          如果用gb2312編譯,你會找到e4 bd a0的字段 ;
          如果用8859_1編譯, 00c4 00e3的二進制:
          0000,0000 ,1100,0100 ,0000,0000 ,1110,0011
          因為每個字符都大于7位,因此用11位編碼:
          1100,0001,1000,0100,1100,0011,1010,0011
          c1-- 84-- c3--  a3
          你會找到c1 84 c3 a3

          ?

          但是我們往往忽略掉這個參數,因此這樣往往會有跨平臺的問題:

          樣例代碼在中文平臺上編譯,生成zhclass

          樣例代碼在英文平臺上編譯,輸出enclass

          (1) zhclass在中文平臺上執行ok,但是在英文平臺上不行

          (2) enclass在英文平臺上執行ok,但是在中文平臺上不行

          原因是:

          (1) 在中文平臺上編譯后,其實str在運行態的char[]是0x4f60, 在中文平臺上運行,filewriter的缺省編碼是gb2312,因此chartobyteconverter會自動用調用gb2312的converter,把str轉化成byte輸入到fileoutputstream中,于是0xc4,0xe3放進了文件。但是如果是在英文平臺下,chartobyteconverter的缺省值是8859_1, filewriter會自動調用8859_1去轉化str,但是他無法解釋,因此他會輸出"?"

          (2) 在英文平臺上編譯后,其實str在運行態的char[]是0x00c4 0x00e3, 在中文平臺上運行,中文無法識別,因此會出現??;在英文平臺上,0x00c4-->0xc4,0x00e3->0xe3,因此0xc4,0xe3被放進了文件。

          六、其它原因:


          <%@ page contentType="text/html; charset=GBK" %>

          ?

          設置瀏覽器的顯示編碼,如果response的數據是utf8編碼,顯示將是亂碼,但是亂碼和上述原因還不一樣。

          七、發生編碼的地方:

          1. 從數據庫到Java程序 byte——〉char

          2. 從Java程序到數據庫 char——〉byte

          3. 從文件到Java程序 byte——〉char

          4. 從Java程序到文件 char——〉byte

          5. 從Java程序到頁面顯示 char——〉byte

          6. 從頁面form提交數據到Java程序byte——〉char

          7. 從流到Java程序byte——〉char

          8. 從Java程序到流char——〉byte

          可以使用配置過濾器的方法解決中文亂碼的:


          <web-app>
          ? <filter>
          ??? <filter-name>RequestFilter</filter-name>
          ??? <filter-class>net.golden.uirs.util.RequestFilter</filter-class>
          ??? <init-param>
          ????? <param-name>charset</param-name>
          ????? <param-value>gb2312</param-value>
          ??? </init-param>
          ? </filter>
          ? <filter-mapping>
          ??? <filter-name>RequestFilter</filter-name>
          ??? <url-pattern>*.Jsp</url-pattern>
          ? </filter-mapping>
          </web-app>


          ? public void doFilter(ServletRequest req, ServletResponse res,
          ?????????????????????? FilterChain fChain) throws IOException, ServletException {
          ??? HttpServletRequest request = (HttpServletRequest) req;
          ??? HttpServletResponse response = (HttpServletResponse) res;
          ??? HttpSession session = request.getSession();
          ??? String userId = (String) session.getAttribute("userid");
          req.setCharacterEncoding(this.filterConfig.getInitParameter("charset"));
          // 設置字符集?
          實際上是設置了byte ——〉char的encoding
          ??? try {
          ????? if (userId == null || userId.equals("")) {
          ??????? if (!request.getRequestURL().toString().matches(
          ??????????? ".*/uirs/logon/logon(Controller){0,1}\\x2EJsp$")) {
          ????????? session.invalidate();
          ????????? response.sendRedirect(request.getContextPath() +
          ??????????????????????????????? "/uirs/logon/logon.Jsp");
          ??????? }
          ????? }
          ????? else {
          ?? // 看看是否具有信息上報系統的權限
          ??????? if (!net.golden.uirs.util.UirsChecker.check(userId, "信息上報系統",
          ??????????? net.golden.uirs.util.UirsChecker.ACTION_DO)) {
          ????????? if (!request.getRequestURL().toString().matches(
          ????????????? ".*/uirs/logon/logon(Controller){0,1}\\x2EJsp$")) {
          ??????????? response.sendRedirect(request.getContextPath() +
          ????????????????????????????????? "/uirs/logon/logonController.Jsp");
          ????????? }
          ??????? }
          ????? }
          ??? }
          ??? catch (Exception ex) {
          ????? response.sendRedirect(request.getContextPath() +
          ??????????????????????????? "/uirs/logon/logon.Jsp");
          ??? }
          ??? fChain.doFilter(req, res);
          ? }

          ?

          ?

          posted @ 2006-09-28 00:27 xyang 閱讀(147) | 評論 (0)編輯 收藏

          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-09-28 00:25 xyang 閱讀(197) | 評論 (0)編輯 收藏

          算法常用術語中英對照

          Data Structures 基本數據結構
          Dictionaries 字典
          Priority Queues 堆
          Graph Data Structures 圖
          Set Data Structures 集合
          Kd-Trees 線段樹
          Numerical Problems 數值問題
          Solving Linear Equations 線性方程組
          Bandwidth Reduction 帶寬壓縮
          Matrix Multiplication 矩陣乘法
          Determinants and Permanents 行列式
          Constrained and Unconstrained Optimization 最值問題
          Linear Programming 線性規劃
          Random Number Generation 隨機數生成
          Factoring and Primality Testing 因子分解/質數判定
          Arbitrary Precision Arithmetic 高精度計算
          Knapsack Problem 背包問題
          Discrete Fourier Transform 離散Fourier變換
          Combinatorial Problems 組合問題
          Sorting 排序
          Searching 查找
          Median and Selection 中位數
          Generating Permutations 排列生成
          Generating Subsets 子集生成
          Generating Partitions 劃分生成
          Generating Graphs 圖的生成
          Calendrical Calculations 日期
          Job Scheduling 工程安排
          Satisfiability 可滿足性
          Graph Problems -- polynomial 圖論-多項式算法
          Connected Components 連通分支
          Topological Sorting 拓撲排序
          Minimum Spanning Tree 最小生成樹
          Shortest Path 最短路徑
          Transitive Closure and Reduction 傳遞閉包
          Matching 匹配
          Eulerian Cycle / Chinese Postman Euler回路/中國郵路
          Edge and Vertex Connectivity 割邊/割點
          Network Flow 網絡流
          Drawing Graphs Nicely 圖的描繪
          Drawing Trees 樹的描繪
          Planarity Detection and Embedding 平面性檢測和嵌入
          Graph Problems -- hard 圖論-NP問題
          Clique 最大團
          Independent Set 獨立集
          Vertex Cover 點覆蓋
          Traveling Salesman Problem 旅行商問題
          Hamiltonian Cycle Hamilton回路
          Graph Partition 圖的劃分
          Vertex Coloring 點染色
          Edge Coloring 邊染色
          Graph Isomorphism 同構
          Steiner Tree Steiner樹
          Feedback Edge/Vertex Set 最大無環子圖
          Computational Geometry 計算幾何
          Convex Hull 凸包
          Triangulation 三角剖分
          Voronoi Diagrams Voronoi圖
          Nearest Neighbor Search 最近點對查詢
          Range Search 范圍查詢
          Point Location 位置查詢
          Intersection Detection 碰撞測試
          Bin Packing 裝箱問題
          Medial-Axis Transformation 中軸變換
          Polygon Partitioning 多邊形分割
          Simplifying Polygons 多邊形化簡
          Shape Similarity 相似多邊形
          Motion Planning 運動規劃
          Maintaining Line Arrangements 平面分割
          Minkowski Sum Minkowski和
          Set and String Problems 集合與串的問題
          Set Cover 集合覆蓋
          Set Packing 集合配置
          String Matching 模式匹配
          Approximate String Matching 模糊匹配
          Text Compression 壓縮
          Cryptography 密碼
          Finite State Machine Minimization 有窮自動機簡化
          Longest Common Substring 最長公共子串
          Shortest Common Superstring 最短公共父串
          DP——Dynamic Programming——動態規劃
          recursion —— 遞歸

          編程詞匯
          A2A integration? A2A整合???????
          abstract?? 抽象的????????
          abstract base class (ABC)抽象基類
          abstract class 抽象類
          abstraction 抽象、抽象物、抽象性
          access 存取、訪問
          access level訪問級別
          access function? 訪問函數
          account? 賬戶
          action?? 動作
          activate 激活
          active?? 活動的
          actual parameter? 實參
          adapter 適配器
          add-in? 插件
          address 地址
          address space???? 地址空間
          address-of operator 取地址操作符
          ADL (argument-dependent lookup)
          ADO(ActiveX Data Object)ActiveX數據對象
          advanced??? 高級的
          aggregation 聚合、聚集
          algorithm 算法
          alias 別名
          align 排列、對齊
          allocate 分配、配置
          allocator分配器、配置器
          angle bracket 尖括號
          annotation?? 注解、評注
          API (Application Programming Interface) 應用(程序)編程接口
          app domain (application domain)應用域
          application? 應用、應用程序
          application framework 應用程序框架
          appearance 外觀
          append???? 附加
          architecture 架構、體系結構
          archive file 歸檔文件、存檔文件
          argument引數(傳給函式的值)。參見parameter??????????
          array?? 數組
          arrow operator? 箭頭操作符
          ASP(Active Server Page)活動服務器頁面
          ASP.NET worker process ASP.NET工作者進程
          assembly???? 裝配件、配件
          assembly language?? 匯編語言
          assembly manifest?? 裝配件清單
          assert(ion) 斷言
          assign????? 賦值
          assignment? 賦值、分配
          assignment operator 賦值操作符
          associated? 相關的、相關聯的
          associative container 關聯式容器(對應sequential container)????????
          asynchronous? 異步的
          atomic??? 原子的
          atomic operation?? 原子操作
          attribute?? 特性、屬性
          authentication service 驗證服務
          authorization? 授權
          audio?? 音頻
          A.I.??? 人工智能
          B2B integration? B2B整合、B2B集成(business-to-business integration)????????
          background?? 背景、后臺(進程)
          backward compatible??? 向后兼容、向下兼容
          backup?? 備份
          backup device備份設備
          backup file? 備份文件
          bandwidth? 帶寬
          base class 基類
          base type? 基類型
          batch?? 批處理
          BCL (base class library)基類庫
          binary? 二進制??
          binary search 二分查找
          binary tree 二叉樹
          binary function? 雙參函數
          binary large object二進制大對象
          binary operator 二元操作符
          binding 綁定
          bit 位
          bitmap? 位圖
          bitwise 按位...
          bitwise copy?????? 為單元進行復制;位元逐一復制,按位拷
          bitwise operation? 按位運算
          block? 塊、區塊、語句塊
          bookkeeping? 簿記
          boolean 布林值(真假值,true或false)?????????????????
          border? 邊框
          bounds checking 邊界檢查
          boxing? 裝箱、裝箱轉換
          brace (curly brace) 大括號、花括號
          bracket (square brakcet) 中括號、方括號
          breakpoint 斷點
          browser applications? 瀏覽器應用(程序)
          browser-accessible application? 可經由瀏覽器訪問的應用程序
          build? 編連(專指編譯和連接
          built-in? 內建、內置
          bus? 總線
          business? 業務、商務(看場合)
          business Logic 業務邏輯
          business rules 業務規則
          buttons? 按鈕
          bug? 臭蟲
          by/through 通過
          byte? 位元組(由8 bits組成)???
          cache 高速緩存
          calendar 日歷
          call 調用
          callback? 回調
          call-level interface (CLI)調用級接口(CLI)
          call operator 調用操作符
          candidate key 候選鍵 (for database)
          cascading delete 級聯刪除 (for database)
          cascading update 級聯更新 (for database)
          casting?? 轉型、造型轉換
          catalog?? 目錄
          chain???? 鏈(function calls)
          character 字符
          character format? 字符格式
          character set???? 字符集
          CHECK constraints CHECK約束 (for database)
          checkpoint 檢查點 (for database)
          check box? 復選框
          check button 復選按鈕
          child class? 子類
          CIL (common intermediate language)通用中間語言、通用中介語言
          class??? 類
          class declaration? 類聲明
          class definition?? 類定義
          class derivation list 類繼承列表
          class factory??? 類廠
          class hierarchy? 類層次結構
          class library??? 類庫
          class loader???? 類裝載器
          class template?? 類模板
          class template partial specializations 類模板部分特化
          class template specializations???????? 類模板特化
          classification? 分類
          clause? 子句
          client application? 客戶端應用程序
          client cursor? 客戶端游標 (for database)
          code page 代碼頁
          cleanup?? 清理、清除
          CLI (Common Language Infrastructure)?? 通用語言基礎設施
          client 客戶、客戶端
          client area? 客戶區
          client-server 客戶機/服務器、客戶端/服務器
          clipboard 剪貼板
          clone? 克隆
          CLS (common language specification) 通用語言規范
          code access security? 代碼訪問安全
          COFF (Common Object File Format)??? 通用對象文件格式
          collection? 集合
          COM (Component Object Model)? 組件對象模型
          combo box 組合框
          command line 命令行
          comment? 注釋
          commit?? 提交 (for database)
          communication? 通訊
          compatible 兼容
          compile time 編譯期、編譯時
          compiler 編譯器
          component組件
          composite index 復合索引、組合索引 (for database)
          composite key 復合鍵、組合鍵 (for database)
          composition?? 復合、組合
          concept 概念
          concrete具體的
          concrete class? 具體類
          concurrency 并發、并發機制
          constraint? 約束 (for database)
          configuration 配置、組態
          connection??? 連接 (for database)
          connection pooling 連接池
          console??? 控制臺
          constant?? 常量
          construct? 構件、成分、概念、構造(for language)
          constructor (ctor) 構造函數、構造器
          container? 容器
          containment包容
          context 環境、上下文
          control 控件
          cookie? (不譯)
          copy??? 拷貝
          CORBA?? 通用對象請求中介架構(Common Object Request Broker Architecture)
          cover?? 覆蓋、涵蓋
          create/creation??? 創建、生成
          crosstab query???? 交叉表查詢 (for database)
          CRTP (curiously recurring template pattern)
          CTS (common type system)通用類型系統
          cube?? 多維數據集 (for database)
          cursor 光標
          cursor 游標 (for database)
          custom 定制、自定義
          data?? 數據
          data connection?? 數據連接 (for database)
          Data Control Language (DCL)? 數據控制語言(DCL) (for database)
          Data Definition Language (DDL) 數據定義語言(DDL) (for database)
          data dictionary 數據字典 (for database)
          data dictionary view? 數據字典視圖 (for database)
          data file? 數據文件 (for database)
          data integrity? 數據完整性 (for database)
          data manipulation language (DML)數據操作語言(DML) (for database)
          data mart? 數據集市 (for database)
          data pump? 數據抽取 (for database)
          data scrubbing? 數據清理 (for database)
          data source???? 數據源 (for database)
          Data source name (DSN) 數據源名稱(DSN) (for database)
          data warehouse??? 數據倉庫 (for database)
          dataset?? 數據集 (for database)
          database? 數據庫 (for database)
          database catalog? 數據庫目錄 (for database)
          database diagram? 數據關系圖 (for database)
          database file???? 數據庫文件 (for database)
          database object?? 數據庫對象 (for database)
          database owner??? 數據庫所有者 (for database)
          database project? 數據庫工程 (for database)
          database role???? 數據庫角色 (for database)
          database schema? 數據庫模式、數據庫架構 (for database)
          database script? 數據庫腳本 (for database)
          data-bound?????? 數據綁定 (for database)
          data-aware control數據感知控件 (for database)
          data member?? 數據成員、成員變量
          dataset?????? 數據集 (for database)
          data source?? 數據源 (for database)
          data structure數據結構
          data table??? 數據表 (for database)
          datagram??? 數據報文
          DBMS (database management system)數據庫管理系統 (for database)
          DCOM (distributed COM)分布式COM
          dead lock? 死鎖 (for database)
          deallocate 歸還
          debug????? 調試
          debugger?? 調試器
          decay????? 退化
          decision support 決策支持
          declaration 聲明
          declarative referential integrity (DRI)聲明引用完整性(DRI) (for database)
          deduction? 推導
          DEFAULT constraint默認約束 (for database)
          default database? 默認數據庫 (for database)
          default instance? 默認實例 (for database)
          default result set 默認結果集 (for database)
          default???? 缺省、默認值
          defer?????? 推遲
          definition? 定義
          delegate??? 委托
          delegation? 委托
          dependent name??????
          deploy?????? 部署
          dereference? 解引用
          dereference operator (提領)運算子?????????????????????
          derived class? 派生類
          design by contract 契約式設計
          design pattern? 設計模式
          destroy?? 銷毀
          destructor(dtor)析構函數、析構器
          device?? 設備
          DHTML (dynamic HyperText Markup Language)動態超文本標記語言
          dialog?? 對話框
          digest?? 摘要
          digital? 數字的
          DIME (Direct Internet Message Encapsulation)直接Internet消息封裝
          directive? (編譯)指示符
          directory? 目錄
          dirty pages臟頁 (for database)
          dirty read 臟讀 (for database)
          disassembler 反匯編器
          DISCO (Discovery of Web Services)Web Services的查找
          disk? 盤
          dispatch 調度、分派、派發(我喜歡“調度”)
          DISPID (Dispatch Identifier)分派標識符
          distributed computing 分布式計算
          distributed query???? 分布式查詢 (for database)
          DNA (Distributed interNet Application) 分布式網間應用程序
          document 文檔
          DOM (Document Object Model)文檔對象模型
          dot operator? (圓)點操作符
          driver 驅動(程序)
          DTD (document type definition)? 文檔類型定義
          double-byte character set (DBCS)雙字節字符集(DBCS)
          dump?????? 轉儲
          dump file? 轉儲文件
          dynamic cursor??? 動態游標 (for database)
          dynamic filter??? 動態篩選 (for database)
          dynamic locking?? 動態鎖定 (for database)
          dynamic recovery? 動態恢復 (for database)
          dynamic snapshot? 動態快照 (for database)
          dynamic SQL statements 動態SQL語句 (for database)
          dynamic assembly 動態裝配件、動態配件
          dynamic binding? 動態綁定
          EAI (enterprise application integration)企業應用程序集成(整合)
          EBCO (empty base class optimization)?? 空基類優化(機制)
          e-business?? 電子商務
          EDI (Dlectronic Data Interchange)電子數據交換
          efficiency 效率
          efficient? 高效
          end-to-end authentication 端對端身份驗證
          end user 最終用戶
          engine?? 引擎
          entity? 實體
          encapsulation?? 封裝
          enclosing class 外圍類別(與巢狀類別 nested class有關)
          enum (enumeration) 枚舉
          enumerators 枚舉成員、枚舉器
          equal?????? 相等
          equality??? 相等性
          equality operator? 等號操作符
          error log?? 錯誤日志 (for database)
          escape code 轉義碼
          escape character 轉義符、轉義字符
          exclusive lock?? 排它鎖 (for database)
          explicit transaction 顯式事務 (for database)
          evaluate 評估
          event??? 事件
          event driven? 事件驅動的
          event handler 事件處理器
          evidence? 證據
          exception 異常
          exception declaration 異常聲明
          exception handling 異常處理、異常處理機制
          exception-safe 異常安全的
          exception specification 異常規范
          exit???? 退出
          explicit 顯式
          explicit specialization? 顯式特化
          export????? 導出
          expression? 表達式
          facility??? 設施、設備
          fat client? 胖客戶端
          feature???? 特性、特征
          fetch 提取
          field 字段(java)
          field 字段 (for database)
          field length 字段長度 (for database)
          file?? 文件
          filter 篩選 (for database)
          finalization 終結
          firewall? 防火墻
          finalizer 終結器
          firmware 固件
          flag???? 標記
          flash memory 閃存
          flush 刷新
          font? 字體
          foreign key (FK)? 外鍵(FK) (for database)
          form?? 窗體
          formal parameter? 形參
          forward declaration? 前置聲明
          forward-only? 只向前的
          forward-only cursor? 只向前游標 (for database)
          fragmentation 碎片 (for database)
          framework? 框架
          full specialization? 完全特化
          function? 函數
          function call operator (即operator ()) 函數調用操作符
          function object 函數對象
          function overloaded resolution函數重載決議
          functionality??? 功能
          function template函數模板
          functor? 仿函數
          GAC (global assembly cache) 全局裝配件緩存、全局配件緩存
          GC (Garbage collection)???? 垃圾回收(機制)、垃圾收集(機制)
          game???? 游戲
          generate 生成
          generic? 泛化的、一般化的、通用的
          generic algorithm通用算法
          genericity 泛型
          getter (相對于 setter)取值函數
          global??????? 全局的
          global object 全局對象
          global scope resolution operator 全局范圍解析操作符
          grant?????? 授權 (for database)
          granularity 粒度
          group?????? 組、群
          group box?? 分組框
          GUI?? 圖形界面
          GUID (Globally Unique Identifier) 全球唯一標識符
          hand shaking?? 握手
          handle???? 句柄
          handler??? 處理器
          hard-coded 硬編碼的
          hard-copy? 截屏圖
          hard disk? 硬盤
          hardware?? 硬件
          hash table 散列表、哈希表
          header file頭文件
          heap?????? 堆
          help file? 幫助文件
          hierarchy? 層次結構、繼承體系
          hierarchical data 階層式數據、層次式數據
          hook?? 鉤子
          Host (application)宿主(應用程序)
          hot key?? 熱鍵
          hyperlink 超鏈接
          HTML (HyperText Markup Language) 超文本標記語言
          HTTP pipeline? HTTP管道
          HTTP (HyperText Transfer Protocol) 超文本傳輸協議
          icon?? 圖標
          IDE (Integrated Development Environment)集成開發環境
          IDL (Interface Definition Language)??? 接口定義語言
          identifier 標識符
          idle time? 空閑時間
          if and only if當且僅當
          IL (Intermediate Language) 中間語言、中介語言
          image 圖象
          IME?? 輸入法
          immediate base????? 直接基類
          immediate derived?? 直接派生類
          immediate updating? 即時更新 (for database)
          implicit transaction隱式事務 (for database)
          incremental update? 增量更新 (for database)
          index????????? 索引 (for database)
          implement????? 實現
          implementation 實現、實現品
          implicit?????? 隱式
          import???????? 導入
          increment operator? 增加操作符
          infinite loop?????? 無限循環
          infinite recursive? 無限遞歸
          information????? 信息
          infrastructure?? 基礎設施
          inheritance????? 繼承、繼承機制
          inline?????????? 內聯
          inline expansion 內聯展開
          initialization?? 初始化
          initialization list 初始化列表、初始值列表
          initialize????? 初始化
          inner join????? 內聯接 (for database)
          in-place active 現場激活
          instance??????? 實例
          instantiated??? 具現化、實體化(常應用于template)????????????
          instantiation?? 具現體、具現化實體(常應用于template)????????
          integrate?????? 集成、整合
          integrity?????? 完整性、一致性
          integrity constraint完整性約束 (for database)
          interprocess communication (IPC)進程間通訊(IPC)
          interacts? 交互
          interface? 接口
          ? for GUI? 界面
          interoperability 互操作性、互操作能力
          interpreter?? 解釋器
          introspection 自省
          invariants??? 不變性
          invoke??????? 調用
          isolation level? 隔離級別 (for database)
          iterate?? 迭代
          iterative 反復的、迭代的
          iterator? 迭代器
          iteration 迭代(回圈每次輪回稱為一個iteration)?????????
          item????? 項、條款、項目
          JIT compilation? JIT編譯 即時編譯
          key????????? 鍵 (for database)
          key column?? 鍵列 (for database)
          laser??????? 激光
          late binding 遲綁定
          left outer join? 左向外聯接 (for database)
          level????? 階、層例
          high level 高階、高層
          library??? 庫
          lifetime?? 生命期、壽命
          link?????? 連接、鏈接
          linkage??? 連接、鏈接
          linker???? 連接器、鏈接器
          literal constant 字面常數
          list?? 列表、表、鏈表
          list box 列表框
          livelock 活鎖 (for database)
          load?? 裝載、加載
          load balancing? 負載平衡
          loader 裝載器、載入器
          local? 局部的
          local object??? 局部對象
          lock? 鎖
          log?? 日志
          login 登錄
          login security mode登錄安全模式 (for database)
          lookup table?? 查找表 (for database)
          loop?????????? 循環
          loose coupling 松散耦合
          lvalue???????? 左值
          machine code?? 機器碼、機器代碼
          macro??????? 宏
          maintain???? 維護
          managed code 受控代碼、托管代碼
          Managed Extensions 受控擴充件、托管擴展
          managed object 受控對象、托管對象
          mangled name??????
          manifest???? 清單
          manipulator? 操縱器(iostream預先定義的一種東西)???????????
          many-to-many relationship 多對多關系 (for database)
          many-to-one relationship? 多對一關系 (for database)
          marshal? 列集
          member?? 成員
          member access operator??? 成員取用運算子(有dot和arrow兩種)????????????
          member function?????????? 成員函數
          member initialization list成員初始值列表
          memberwise? 以member為單元…、members 逐一…???????????
          memberwise copy?
          memory????? 內存
          memory leak 內存泄漏
          menu???? 菜單
          message? 消息
          message based? 基于消息的
          message loop?? 消息環
          message queuing消息隊列
          metadata 元數據
          metaprogramming元編程
          method 方法
          micro? 微
          middleware? 中間件
          middle tier 中間層
          modeling??? 建模
          modeling language 建模語言
          modifier? 修飾字、修飾符
          modem???? 調制解調器
          module??? 模塊
          most derived class最底層的派生類
          mouse?? 鼠標
          mutable 可變的
          mutex?? 互斥元、互斥體
          multidimensional OLAP (MOLAP)??? 多維OLAP(MOLAP) (for database)
          multithreaded server application 多線程服務器應用程序
          multiuser?????? 多用戶
          multi-tasking?? 多任務
          multi-thread??? 多線程
          multicast delegate 組播委托、多點委托
          named parameter??? 命名參數
          named pipe? 命名管道
          namespace?? 名字空間、命名空間
          native????? 原生的、本地的
          native code 本地碼、本機碼
          Native Image Generator (NGEN)本地映像生成器
          nested class? 嵌套類
          nested query? 嵌套查詢 (for database)
          nested table? 嵌套表 (for database)
          network?????? 網絡
          network card? 網卡
          nondependent name
          object??????? 對象
          object based? 基于對象的
          object file?? 目標文件
          object model? 對象模型
          object oriented 面向對象的
          object pooling? 對象池化
          ODBC data source ODBC數據源 (for database)
          ODBC driver????? ODBC驅動程序 (for database)
          ODR (one-definition rule)
          OLE Automation objects?? OLE自動化對象 (for database)
          OLE Automation server??? OLE自動化服務器 (for database)
          OLE DB consumer? OLE DB使用者 (for database)
          OLE DB for OLAP? 用于OLAP的OLE DB (for database)
          OLE DB provider? OLE DB提供者 (for database)
          one-to-many relationship 一對多關系 (for database)
          one-to-one relationship? 一對一關系 (for database)
          online analytical processing (OLAP)??? 聯機分析處理(OLAP) (for database)
          online redo log???? 聯機重做日志 (for database)
          online transaction processing (OLTP)?? 聯機事務處理(OLTP) (for database)
          Open Data Services (ODS)?? 開放式數據服務(ODS) (for database)
          Open Database Connectivity (ODBC) 開放式數據庫連接(ODBC) (for database)
          operand?? 操作數
          operating system (OS) 操作系統
          operation? 操作
          operator?? 操作符、運算符
          option???? 選項
          optimizer? 優化器
          outer join 外聯接 (for database)
          overflow?? 上限溢位(相對于underflow)???????????????????
          overhead?? 額外開銷
          overload?? 重載
          overload resolution?? 重載決議
          overloaded function?? 重載的函數
          overloaded operator? 被重載的操作符
          override?? 覆寫、重載、重新定義
          package??? 包
          packaging? 打包
          palette??? 調色板
          parallel?? 并行
          parameter? 參數、形式參數、形參
          parameter list 參數列表
          parameterize?? 參數化
          parent class?? 父類
          parentheses??? 圓括弧、圓括號
          parse??? 解析
          parser?? 解析器
          part???? 零件、部件
          partial specialization 局部特化
          pass by address?? 傳址(函式引數的傳遞方式)(非正式用語)????????
          pass by reference 傳地址、按引用傳遞
          pass by value 按值傳遞
          pattern?????? 模式
          PDA (personal digital assistant)個人數字助理
          PE (Portable Executable) file?? 可移植可執行文件
          performance?? 性能
          persistence?? 持久性
          PInvoke (platform invoke service) 平臺調用服務
          pixel? 像素
          placement delete
          placement new???
          placeholder 占位符
          platform??? 平臺
          POD (plain old data (type))????????
          POI (point of instantiation)????????????????
          pointer? 指針
          poll???? 輪詢
          pooling? 池化
          polymorphism? 多態
          pop up???? 彈出式
          port?????? 端口
          postfix??? 后綴
          precedence 優先序(通常用于運算子的優先執行次序)????????
          prefix???? 前綴
          preprocessor??? 預處理器
          primary key (PK)主鍵(PK)? (for database)
          primary table?? 主表 (for database)
          primary template原始模板
          primitive type? 原始類型
          print????? 打印
          printer??? 打印機
          procedure? 過程
          procedural 過程式的、過程化的
          process??? 進程
          profile??? 評測
          profiler?? 效能(性能)評測器
          program??? 程序
          programmer 程序員
          programming編程、程序設計
          progress bar 進度指示器
          project??? 項目、工程
          property?? 屬性
          protocol?? 協議
          pseudo code偽碼
          qualified? 經過資格修飾(例如加上scope運算子)???????????
          qualified name
          qualifier 修飾符
          quality?? 質量
          queue???? 隊列
          race condition 競爭條件(多線程環境常用語)
          radian???????? 弧度
          radio button?? 單選按鈕
          raise????????? 引發(常用來表示發出一個exception)???????????
          random number? 隨機數
          range?? 范圍、區間
          rank??? 等級
          raw???? 未經處理的
          readOnly只讀
          record? 記錄 (for database)
          recordset? 記錄集 (for database
          recursive? 遞歸
          re-direction? 重定向
          refactoring?? 重構
          refer???? 引用、參考
          reference 引用、參考
          reference counting引用計數
          referential integrity (RI)引用完整性(RI) (for database)
          register???? 寄存器
          reflection?? 反射
          refresh data 刷新數據 (for database)
          regular expression? 正則表達式
          relational database 關系數據庫
          remote???????? 遠程
          remote request 遠程請求
          represent????? 表述,表現
          resolve??????? 解析、決議????????
          resolution???? 解析過程
          result set???? 結果集 (for database)
          retrieve data? 檢索數據??
          return???????? 返回
          return type??? 返回類型
          return value?? 返回值
          right outer join? 右向外聯接 (for database)
          revoke?????? 撤銷
          robust?????? 健壯
          robustness?? 健壯性
          roll back??? 回滾 (for database)
          roll forward 前滾 (for database)
          routine????? 例程
          row????????? 行 (for database)
          row lock???? 行鎖 (for database)
          rowset?????? 行集 (for database)
          RPC (remote procedure call)RPC(遠程過程調用)
          runtime 執行期、運行期、執行時、運行時
          rvalue? 右值
          save??? 保存
          savepoint? 保存點 (for database)
          SAX (Simple API for XML)
          scalable? 可伸縮的、可擴展的
          schedule? 調度
          scheduler 調度程序
          schema??? 模式、綱目結構
          scroll bar滾動條
          scope???? 作用域、生存空間
          scope operator 生存空間操作符
          scope resolution operator 生存空間解析操作符
          screen?? 屏幕
          SDK (Software Development Kit)軟件開發包
          sealed class 密封類
          search??? 查找
          semantics 語義
          semaphore 信號量
          sequential container序列式容器
          server??? 服務器、服務端
          serial??? 串行
          serialization/serialize 序列化
          server cursor服務端游標、服務器游標 (for database)
          session????? 會話 (for database)
          setter?????? 設值函數
          shared lock? 共享鎖 (for database)
          sibling????? 同級
          side effect? 副作用
          signature??? 簽名
          single-threaded? 單線程
          slider滑塊
          slot? 槽
          smart pointer 智能指針
          SMTP (Simple Mail Transfer Protocol)?? 簡單郵件傳輸協議
          snapshot?????? 截屏圖
          snapshot?????? 快照 (for database)
          specialization 特化
          specification? 規范、規格
          splitter?????? 切分窗口
          SOAP (simple object access protocol)?? 簡單對象訪問協議
          software????? 軟件
          source code?? 源碼、源代碼
          SQL (Structured Query Language)? 結構化查詢語言 (for database)
          stack? 棧、堆棧
          stack unwinding?? 疊輾轉開解(此詞用于exception主題)?????????
          standard library? 標準庫???????
          standard template library 標準模板庫
          stateless 無狀態的
          statement 語句、聲明
          static cursor 靜態游標 (for database)
          static SQL statements 靜態SQL語句 (for database)
          stored procedure 存儲過程 (for database)
          status bar 狀態條
          stream?? 流
          string?? 字符串
          stub???? 存根
          subobject子對象
          subquery 子查詢 (for database)
          subroutine? 子例程
          subscript operator 下標操作符
          subset?? 子集
          subtype? 子類型
          support? 支持
          suspend? 掛起
          symbol?? 記號
          syntax?? 語法
          system databases?? 系統數據庫 (for database)
          system tables????? 系統表 (for database)
          table?????? 表 (for database)
          table lock? 表鎖 (for database)
          table-level constraint 表級約束 (for database)
          tape backup? 磁帶備份 (for database)
          target? 標的,目標
          task switch? 工作切換?????????????
          TCP (Transport Control Protocol)?????? 傳輸控制協議
          template?????? 模板
          template-id
          template argument deduction????? 模板參數推導
          template explicit specialization 模板顯式特化
          template parameter?? 模板參數
          template template parameter
          temporary object 臨時對象
          temporary table? 臨時表 (for database)
          text 文本
          text file?? 文本文件
          thin client 瘦客戶端
          third-party 第三方
          thread????? 線程
          thread-safe 線程安全的
          throw 拋出、引發(常指發出一個exception)??????
          token 符號、標記、令牌(看場合)
          trace 跟蹤
          transaction 事務 (for database)
          transaction log? 事務日志 (for database)
          transaction rollback? 事務回滾 (for database)
          transactional replication? 事務復制 (for database)
          translation unit 翻譯單元
          traverse 遍歷
          trigger? 觸發器 (for database)
          two-phase commit 兩階段提交 (for database)
          tuple
          two-phase lookup 兩階段查找
          type? 類型
          UDDI(Universary Description, Discovery and Integration)統一描述、查詢與集成
          UML (unified modeling language)統一建模語言
          unary function 單參函數
          unary operator 一元操作符
          unboxing?????? 拆箱、拆箱轉換
          underflow????? 下限溢位(相對于overflow)
          Union query??? 聯合查詢 (for database)
          UNIQUE constraints? UNIQUE約束 (for database)
          unique index?? 唯一索引 (for database)
          unmanaged code 非受控代碼、非托管代碼
          unmarshal????? 散集
          unqualified???? 未經限定的、未經修飾的
          URI (Uniform Resource identifier) 統一資源標識符
          URL (Uniform Resource Locator)??? 統一資源定位器
          user??????????? 用戶
          user interface? 用戶界面
          value types 值類型
          variable 變量
          vector?? 向量(一種容器,有點類似array)???????????????
          viable?? 可行的
          video??? 視頻
          view???? 視圖
          VEE (Virtual Execution Engine)虛擬執行引擎
          vendor? 廠商
          view??? 視圖 (for database)
          virtual function? 虛函數
          virtual machine?? 虛擬機
          virtual memory??? 虛擬內存
          vowel????????? 元音字母
          Web Services?? web服務?????
          WHERE clause?? WHERE子句 (for database)
          wildcard characters 通配符字符 (for database)
          wildcard search???? 通配符搜索 (for database)
          window????????????? 窗口
          window function???? 窗口函數
          window procedure??? 窗口過程
          Windows authentication Windows身份驗證
          wizard? 向導
          word??? 單詞
          word processor? 字處理器
          wrapper????? 包裝、包裝器
          write enable 寫啟用 (for database)
          write-ahead log 預寫日志 (for database)
          write-only????? 只寫
          WSDL (Web Service Description Language)Web Service描述語言
          XML Message Interface (XMI)?????? XML消息接口
          XML (eXtensible Markup Language)? 可擴展標記語言
          XSD (XML Schema Definition)?????? XML模式定義語言
          XSL (eXtensible Stylesheet Language) 可擴展樣式表語言
          XSLT (eXtensible Stylesheet Language Transformation)可擴展樣式表語言轉換
          xxx based???? 基于xxx的
          xxx oriented? 面向xxx

          posted @ 2006-09-28 00:23 xyang 閱讀(759) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 温泉县| 循化| 乌兰察布市| 漠河县| 和田市| 洛南县| 三原县| 招远市| 新郑市| 株洲市| 梁河县| 庄浪县| 藁城市| 龙胜| 美姑县| 三台县| 柘荣县| 旅游| 西乡县| 涟源市| 乌兰浩特市| 宁蒗| 岳池县| 和龙市| 晋中市| 青川县| 棋牌| 天长市| 乐至县| 山东| 包头市| 衡山县| 景谷| 太谷县| 奉新县| 韶山市| 婺源县| 樟树市| 上栗县| 锡林郭勒盟| 巴里|