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 阅读(365) | 评论 (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 阅读(662) | 评论 (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 阅读(270) | 评论 (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. </script>
  16. <body onload=”detect()”>
  17. <a id=”list”></a>
  18. </body>
  19. </html>
  20. 这样的通信方式数据量很小,不用重新传递整个页面,5秒钟轮一次,普通PC也能承受较大的在线数。构造一个探测器来监听在线列表和消息,效果是很好的,即使你的客户坐在电脑前袖手旁观,键鼠都不碰一下,也能保证数据即时传递,页面也不会发生跳转和刷新。

      Session监听加上XMLHTTP通信,开发一个较为完善的站内消息系统实在易如反掌

posted @ 2006-10-09 22:58 xyang 阅读(1409) | 评论 (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 阅读(336) | 评论 (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 阅读(913) | 评论 (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 阅读(211) | 评论 (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 阅读(653) | 评论 (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 阅读(292) | 评论 (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 阅读(669) | 评论 (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 阅读(211) | 评论 (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 阅读(375) | 评论 (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 阅读(145) | 评论 (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 阅读(195) | 评论 (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 阅读(757) | 评论 (0)编辑 收藏