ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>国产www.大片在线,亚洲欧洲精品一区二区三区,99国产精品99久久久久久粉嫩http://www.aygfsteel.com/xiaomage234/category/1691.html行到水穷å¤?坐看云è“væ—Óž¼Œæ‰å‘玎ͼšå…¶å®žäººç”Ÿæœ€é‡è¦çš„æ˜¯æ‰‘Öˆ°ä¸€äº›åƒçš„东西;扑ֈ°ä¸€äº›å–çš„东西;扑ֈ°ä¸€äº›å¯ä»¥ä¸€èµäh¬¢½W‘一èµähµæ³ªçš„æœ‹å‹å’Œä¸€ä¸ªæ‡‚你的人!zh-cnFri, 02 Mar 2007 02:38:54 GMTFri, 02 Mar 2007 02:38:54 GMT60(è½?视频聊天原理½Ž€ä»?/title><link>http://www.aygfsteel.com/xiaomage234/articles/6043.html</link><dc:creator>ž®é©¬æ­?/dc:creator><author>ž®é©¬æ­?/author><pubDate>Mon, 13 Jun 2005 08:04:00 GMT</pubDate><guid>http://www.aygfsteel.com/xiaomage234/articles/6043.html</guid><wfw:comment>http://www.aygfsteel.com/xiaomage234/comments/6043.html</wfw:comment><comments>http://www.aygfsteel.com/xiaomage234/articles/6043.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/xiaomage234/comments/commentRss/6043.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/xiaomage234/services/trackbacks/6043.html</trackback:ping><description><![CDATA[<P><FONT size=4>视频聊天原理½Ž€ä»?摄像头的原理介绍<BR><BR>伴随着新经‹¹Žçš„发展åQŒäº’è”ç½‘é€æ¸æˆäØ“äº†ä¸–ç•Œçš„ä¸Õd¯¼åQŒåœ¨çŸ­çŸ­æ•°åòq´çš„æ—‰™—´é‡Œï¼Œ¾|‘络变得­‘Šæ¥­‘Šå®Œå–„,­‘Šæ¥­‘Šå¯çˆ±ï¼Œå®ƒæ‹‰˜q‘了äºÞZ¸ŽäºÞZ¹‹é—´è·¼›»ï¼Œä½¿æˆ‘们的地球变成了一个真正的"村落"åQŒè®©æ›´å¤šçš„äh体会åˆîCº†"íw«éš”千里˜qœï¼Œæƒ…系一¾U‰K—´"的快感ã€?<BR><BR>  ¾|‘络的发展也促进了通讯手段的变化,传统的交‹¹æ–¹å¼å·²¾lä¸èƒ½æ»¡­‘³äh们的要求。从E-mai到Internet PhoneåQŒç½‘¾lœå¸¦æ¥äº†é€šè®¯é€Ÿåº¦çš„æå‡ï¼Œæ›´é™ä½Žäº†é€šè®¯æˆæœ¬ã€‚而随着宽带¾|‘络的普及,äºÞZ»¬å¯¹ç½‘¾lœé€šè®¯ä¹Ÿæœ‰äº†è¿›ä¸€æ­¥çš„要求。宽带网¾lœçš„发展åQŒæ”¹å˜äº†ä¼ ç»Ÿ¾|‘络通讯的质量和形式åQŒä‹É交流不再只是局限于普通语­a€æ–‡å­—åQŒåˆ©ç”¨è§†é¢‘让天各一方的朋友能够彼此相见。作为实现视频聊天的辅助工具åQŒé™¤äº†ä¸€å°é…¾|®ä¸­½{‰çš„ç”?sh¨´)脑外,˜q˜éœ€è¦é…å¤‡ä¸€ä¸?眼睛"。通过它你可以看到å¯ÒŽ(gu¨©)–¹çš„容颜,也让å¯ÒŽ(gu¨©)–¹ä¸€ç¹ä½ çš„风采ã€?<BR>   <BR>ã€€ã€€æ•°ç ç›¸æœºå¯ä»¥ä½œäØ“è§†é¢‘èŠå¤©çš„å·¥å…øP¼Œä½†ä­h(hu¨¢n)格昂è´ëŠš„它用在视频聊天上却多ž®‘有些浪贏V€‚相比,摄像头显然更适合于视频聊天ä‹É用。不仅画质清晎ͼŒæ•捉画面速度快,而且ä»äh ¼ä¾¿å®œåQŒå”®ä»·åœ¨ä¸‰ã€å››ç™‘Ö…ƒã€‚另外,ç”׃ºŽä¸€èˆ¬æ‘„像头采用USB接口åQŒè¿˜å¯ä»¥é›†æˆä¸€äº›è¯¸å¦‚拍照(¾|—技摄像å¤ß_¼‰ã€å­˜å‚¨ï¼ˆè“ç§‘火钻"蓝睛ç?åQ‰ä¹‹¾cȝš„功能åQŒä¸°å¯Œä‹É用空间ã€?   <BR><BR>  摄像头的原理介绍åQ?<BR><BR>  现在市场上销售的摄像头都是数字摄像头åQŒå®ƒ?y¨­u)®†æ‘„åƒå•å…ƒå’Œè§†é¢‘æ•æ‰å•å…ƒé›†æˆåœ¨ä¸€èµøP¼Œé€šè¿‡å¾®æœºä¸Šçš„USB接口åQŒå¯ä»¥å®žçŽ°å³æ’å³ç”¨ï¼Œéžå¸¸é€‚åˆ½W”记本电(sh¨´)脑和品牌机用戗÷€‚例如一些带有拍摄功能的产品。还有一些有闪盘功能的摄像头产品åQŒåœ¨æŽ¥å…¥ç”?sh¨´)脑后还可以当ä½?2MB的闪盘ä‹É用,真正一盘两用ã€?<BR><IMG src="http://img.zol.com.cn/article/0/752/liSethe8k7tuE.jpg" align=middle border=0> <BR>  当然åQŒæ‘„像头基本的功能还是视频传输,那么它是依靠增养的原理来实现的呢åQŸæ‰€è°“视频传输就是将囄¡‰‡ä¸€å¼ å¼ ä¼ åˆ°å±å¹•åQŒç”±äºŽä¼ è¾“速度很快åQŒæ‰€ä»¥å¯ä»¥è®©å¤§å®¶çœ‹åˆ°˜qžç®‹åŠ¨æ€çš„ç”»é¢åQŒå°±åƒæ”¾ç”?sh¨´)媄一栗÷€‚一般当画面的传输数量达到每¿U?4帧时åQŒç”»é¢å°±æœ‰äº†˜qžç®‹æ€§ã€‚在˜q›è¡Œ˜q™ç§å›„¡‰‡çš„传输时åQŒå¿…™åÕd°†å›„¡‰‡˜q›è¡ŒåŽ‹ç¾ƒåQŒä¸€èˆ¬åŽ‹¾~©æ–¹å¼æœ‰å¦‚H.261、JPEG、MPEG½{‰ï¼Œå¦åˆ™ä¼ è¾“所需的带宽会变得很大。大家用RealPlayer不知是否留意åQŒå½“播放ç”?sh¨´)媄的时候,在播攑֙¨çš„下方会有一个传输速度250kbpsã€?00kbpsã€?000kbps...画面的质量越高,˜q™ä¸ªé€Ÿåº¦ä¹Ÿå°±­‘Šå¤§ã€‚而摄像头˜q›è¡Œè§†é¢‘传输也是˜q™ä¸ªåŽŸç†åQŒå¦‚果将摄像头的分èöL率调åˆ?40×480åQŒæ•捉到的图片每张大ž®çº¦ä¸?0kb左右åQŒæ¯¿U?0帧,那么摄像头传输视频所需的速度ä¸?0×30/såQ?500kbpsåQ?.5Mbps。而在实际生活中,äºÞZ»¬ä¸€èˆ¬ç”¨äºŽç½‘¾lœè§†é¢‘聊天时的分辨率ä¸?20×240甚至更低åQŒä¼ è¾“的帧数为每¿U?4帧。换­a€ä¹‹ï¼Œæ­¤æ—¶è§†é¢‘传输速率ž®†ä¸åˆ?00kbpsåQŒäh们就可以˜q›è¡Œè¾ƒäØ“‹¹ç•…的视频传输聊天。如果采用更高的压羃视频方式åQŒå¦‚MPEG-1½{‰ç­‰åQŒå¯ä»¥å°†ä¼ è¾“速率降低åˆ?00kbps不到。这个就是一般视频聊天时åQŒæ‘„像头所需的网¾lœä¼ è¾“速度ã€?<BR><BR>  宽带¾|‘络åQ?<BR><BR>  视频压羃上已¾lå¯ä»¥æ»¡­‘›_º”用的标准åQŒä½†è§†é¢‘聊天的实玎ͼŒ˜q˜éœ€è¦äº’联网条äšg的认可。一般来è¯ß_¼Œåœ¨å›½å†…我们可以通过以下几种方式上网åQ?</FONT> <P> <TABLE align=center border=0> <TBODY> <TR> <TD><FONT size=4><IMG src="http://it.big5.enorth.com.cn/images/show_images_5/03060610.gif" border=0></FONT></TD></TR></TBODY></TABLE></P><FONT size=4>可以看出åQŒé™¤äº?6K ModemåQŒISDN以外åQŒä¸€èˆ¬çš„宽带¾|‘络都可以满­‘³ç”¨æˆ¯‚¿›è¡Œè§†é¢‘传输的需求。而根据不同上¾|‘方式给用户提供的带宽,˜q˜å¯ä»¥è‡ªå·Þp°ƒèŠ‚æ‘„åƒå¤´ä¼ è¾“ç”»é¢çš„è´¨é‡ï¼Œå¦‚åˆ†è¾¨çŽ‡ã€çœŸå½©è‰²¾U§åˆ«ã€ç”»é¢æ•捉传输速度½{‰ç­‰ã€‚比如,当带宽达åˆ?Mbpsæ—Óž¼Œæˆ‘们ž®±å¯ä»¥é‡‡ç”¨åˆ†è¾¨çއä¸?40×480åQŒæ¯¿U?0帧来˜q›è¡Œè§†é¢‘聊天åQŒè¿™æ—¶ä¸è®ºæ˜¯ç”»é¢çš„质量还是流畅性都是相当高的,如同两个人面寚w¢äº¤æµä¸€æ —÷€?   <BR><BR>  现在åQŒæ‘„像头正在向着ž®åž‹åŒ–、功能化的方向发展,­‘Šæ¥­‘Šå¤šçš„附加功能出现在摄像头äñ”品中åQŒä¾‹å¦‚前面提到的可以当作¿UÕdŠ¨å­˜å‚¨ä½¿ç”¨çš„è“¿U‘火é’?蓝睛ç?åQŒå†æ¯”如雅美辄¡š„¾|‘眼昄¡¤ºå™¨ã€ç½—技的摄像头数码相机½{‰ç­‰ã€‚另外,˜q˜æœ‰ä¸€äº›åŽ‚å•†åœ¨æ‘„åƒå¤´çš„å¤–åž‹ä¸Šå¤§åšæ–‡ç« ï¼ŒæŽ¨å‡ºäº†å¤–åž‹è®¾è®¡è®¨å·§çš„"ž®ä¸¸å­?ã€?高达"造型摄像å¤ß_¼Œæ·±å—儿童、女生的喜爱。这么多特色鲜明的äñ”品助阵,再加上网¾lœçš„环境的完善,难怪摄像头会这æ ïL(f¨¥ng)ƒ­å–了ã€?/FONT><img src ="http://www.aygfsteel.com/xiaomage234/aggbug/6043.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/xiaomage234/" target="_blank">ž®é©¬æ­?/a> 2005-06-13 16:04 <a href="http://www.aygfsteel.com/xiaomage234/articles/6043.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(è½?JAVA里字½W¦ç¼–码的探烦与理è§?/title><link>http://www.aygfsteel.com/xiaomage234/articles/5744.html</link><dc:creator>ž®é©¬æ­?/dc:creator><author>ž®é©¬æ­?/author><pubDate>Wed, 08 Jun 2005 08:49:00 GMT</pubDate><guid>http://www.aygfsteel.com/xiaomage234/articles/5744.html</guid><wfw:comment>http://www.aygfsteel.com/xiaomage234/comments/5744.html</wfw:comment><comments>http://www.aygfsteel.com/xiaomage234/articles/5744.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/xiaomage234/comments/commentRss/5744.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/xiaomage234/services/trackbacks/5744.html</trackback:ping><description><![CDATA[<P><FONT size=4>众所周知åQŒJAVAä¸ÞZº†å›½é™…通用åQŒç”¨çš„æ˜¯UNICODE来保存里面的字符。而UNICODE只是一个种字符集,字符的存储和表示要用åˆîC¸€å®šçš„字符¾~–码格式åQŒè€Œä¸ŽUNICODE对应的字½W¦ç¼–码格式就是我们常看到的UTF-8,UTF-16½{‰ç­‰åQŒè€ŒUTF-8是最常用的,所以äh们常常把它和UNICODE½{‰åŒèµäh¥åQˆæˆ‘以前ž®±æ˜¯˜q™æ ·çš„)åQŒè¿™åœ¨æŸäº›æƒ…况下是没有错的,但这æ ïL(f¨¥ng)š„理解在JAVA里就会äñ”ç”Ÿä¸€äº›æØœæ·†ã€‚æˆ‘ä»¬ç”¨ä¸‹é¢çš„ç¨‹åºæ¥æ¼”ç¤ºä¸€ä¸‹ã€?BR>定义一个字½W¦ä¸²</FONT></P> <P><FONT size=4>     String name = "å ?;</FONT></P> <P><FONT size=4>˜q™ä¸ªå­—符串就一个字½W¦ï¼ŒæŠŠå®ƒå–出æ?/FONT></P> <P><FONT size=4>     char c_name = name.charAt(0);</FONT></P> <P><FONT size=4>JAVA里的char型是十六位的åQˆä¸¤ä¸ªå­—节)åQŒä½†æ˜¯å¦‚果是用UTF-8的话可能会不只两位(UTF-8是变长存储的åQ‰ï¼Œé‚£çœ‹æ¥JAVA本èínòq¶ä¸æ˜¯ç”¨UTF-8来保存的åQŒå£è¯´æ— å‡­ï¼Œåšä¸ªå®žéªŒå§ã€?BR>    首先看看char里保存的内容</FONT></P> <P><FONT size=4>int low = (c_name) & 0xff;//取c_name的低ä½?/FONT></P> <P><FONT size=4>int high = (c_name >> 8) & 0xff;//取c_name的高ä½?/FONT></P> <P><FONT size=4>System.out.println(Integer.toHexString(high) + " " + Integer.toHexString(low));</FONT></P> <P><FONT size=4>¾l“æžœæ˜?8 02</FONT></P> <P><FONT size=4>只有两个字节而已åQ?6位)åQŒé‚£ä¹ˆçœŸæ­£çš„UTF-8¾~–码的内å®ÒŽ(gu¨©)˜¯ä»€ä¹ˆå‘¢åQŒå†çœ‹çœ‹å§ã€?/FONT></P> <P><FONT size=4>ä¸ÞZº†æ–¹ä¾¿åQŒæˆ‘写了一个辅助方法printbyteåQŒä½œç”¨æ˜¯æŠŠä¸€ä¸ªbyte数组的每个元素按照十六进制格式打印出来,同样ä¸ÞZº†æ–¹ä¾¿åQŒæˆ‘æŠŠå®ƒä½œäØ“é™æ€æ–¹æ³•ã€?/FONT></P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><FONT size=4><IMG src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> printbyte(</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">[] bt)<BR><IMG id=Codehighlighter1_45_275_Open_Image onclick="this.style.display='none'; Codehighlighter1_45_275_Open_Text.style.display='none'; Codehighlighter1_45_275_Closed_Image.style.display='inline'; Codehighlighter1_45_275_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_45_275_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_45_275_Closed_Text.style.display='none'; Codehighlighter1_45_275_Open_Image.style.display='inline'; Codehighlighter1_45_275_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ContractedBlock.gif" align=top>     </SPAN><SPAN id=Codehighlighter1_45_275_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.aygfsteel.com/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_45_275_Open_Text><FONT size=4><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align=top>         </SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000"> (</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> i </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">; i </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> bt.length; i</SPAN><SPAN style="COLOR: #000000">++</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">)<BR><IMG id=Codehighlighter1_101_219_Open_Image onclick="this.style.display='none'; Codehighlighter1_101_219_Open_Text.style.display='none'; Codehighlighter1_101_219_Closed_Image.style.display='inline'; Codehighlighter1_101_219_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_101_219_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_101_219_Closed_Text.style.display='none'; Codehighlighter1_101_219_Open_Image.style.display='inline'; Codehighlighter1_101_219_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>         </SPAN><SPAN id=Codehighlighter1_101_219_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.aygfsteel.com/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_101_219_Open_Text><FONT size=4><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align=top>              </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> hex </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> (</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">)bt[i] </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">0xff</SPAN></FONT><FONT size=4><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align=top>              System.</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">.print(Integer.toHexString(hex) </SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN></FONT><SPAN style="COLOR: #000000"><FONT size=4>);<BR><IMG src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>         }</FONT></SPAN></SPAN><SPAN style="COLOR: #000000"><BR><FONT size=4><IMG src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align=top>         System.</FONT></SPAN><FONT size=4><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">  length = </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN></FONT><SPAN style="COLOR: #000000"><FONT size=4>bt.length);<BR><IMG src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</FONT></SPAN></SPAN></DIV></DIV> <P><FONT size=4>byte[] utf_8 = name.getBytes("utf-8");</FONT></P> <P><FONT size=4>printbyte(utf_8);</FONT></P> <P><FONT size=4>¾l“果是e5 a0 82   length = 3</FONT></P> <P><FONT size=4>哇,三个字节åQçœ‹æ¥JAVA内部用的真不是UTF-8åQŒé‚£ç”¨çš„æ˜¯ä»€ä¹ˆå‘¢åQŸUTF-16åQŸçœ‹ä¸€ä¸‹ä¾¿çŸ¥ã€?/FONT></P> <P><FONT size=4>     byte[] utf_16 = name.getBytes("utf-16");</FONT></P> <P><FONT size=4>     printbyte(utf_16);</FONT></P> <P><FONT size=4>¾l“果是fe ff 58 02   length = 4åQŒé åQŒå››ä¸ªå­—节了。咦åQŸåŽé¢çš„ä½?6位不正是和开始c_name的十六进制表½CÞZ¸€æ ïL(f¨¥ng)š„吗?看来JAVA真正的内部字½W¦ç¼–码和UTF-16有或多或ž®‘的联系。JAVA内部½I¶ç«Ÿæ˜¯ç”¨çš„什么字½W¦ç¼–码呢åQŸè¿™ä¸ªé—®é¢˜æˆ‘也找了很久,后来在THINK IN JAVA 3rdçš?2章里看到一个例子出çŽîCº†UTF-16BEåQŒéš¾é“是它?</FONT></P> <P><FONT size=4>     byte[] utf_16be = name.getBytes("utf-16be");</FONT></P> <P><FONT size=4>     printbyte(utf_16be);</FONT></P> <P><FONT size=4>¾l“果出来了:58 02   length = 2</FONT></P> <P><FONT size=4>哈哈åQŒI got it!不多不少两个字节åQŒå†…容也一栗÷€‚果然是它。同时我在里面也看到åQŒUNICODE的编码还有一个LEåQŒè¿™é‡Œçš„BE,LE我想应该是bigendianå’Œlittleendian吧ã€?BR></FONT></P><img src ="http://www.aygfsteel.com/xiaomage234/aggbug/5744.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/xiaomage234/" target="_blank">ž®é©¬æ­?/a> 2005-06-08 16:49 <a href="http://www.aygfsteel.com/xiaomage234/articles/5744.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(è½?struts的国际化--UTF-8¾~–码解决http://www.aygfsteel.com/xiaomage234/articles/5743.htmlž®é©¬æ­?/dc:creator>ž®é©¬æ­?/author>Wed, 08 Jun 2005 08:39:00 GMThttp://www.aygfsteel.com/xiaomage234/articles/5743.htmlhttp://www.aygfsteel.com/xiaomage234/comments/5743.htmlhttp://www.aygfsteel.com/xiaomage234/articles/5743.html#Feedback1http://www.aygfsteel.com/xiaomage234/comments/commentRss/5743.htmlhttp://www.aygfsteel.com/xiaomage234/services/trackbacks/5743.html本篇我们来讨è®ÞZ¸€ä¸‹struts的国际化¾~–程问题åQŒå³æ‰€è°“çš„i18n¾~–程问题åQŒè¿™ä¸€½‹‡æˆ‘们讨论其基础部分。与˜q™ä¸ªé—®é¢˜ç´§å¯†ç›¸å…³çš„æ˜¯åœ¨å„javaè®ºå›ä¸­è¢«é¢‘ç¹æåŠçš„ä¸­æ–‡äØ•ç é—®é¢˜ï¼Œå› äØ“åQŒè‹±ã€ç¾Ž¾~–程人员较少涉及åˆîC¸­æ–‡äؕ码问题,因此åQŒè¿™æ–šw¢çš„英文资料也是非常奇¾~ºçš„åQŒåŒæ—¶ä¹Ÿå¾ˆå°‘扑ֈ°˜q™æ–¹é¢æ¯”较完整的中文资料åQŒæœ¬æ–‡ä¹Ÿž®è¯•å¯¹ä¸­æ–‡äØ•ç é—®é¢˜åšä¸€äº›æŽ¢è®¨ã€‚è¦è§£å†³ä¸Šè¿°é—®é¢˜åQŒéœ€è¦æœ‰ä¸€å®šçš„字符集方面的知识åQŒä¸‹é¢ï¼Œæˆ‘们ž®±å…ˆä»‹ç»å­—符集的有关情况åQ?

一、从ASCII到UnicodeåQˆUTF-8åQ?/B>

ç”?sh¨´)子计算机技术是从美国开始发展è“v来的åQŒå› ä¸ºç¾Žå›½ä‹Éç”¨çš„æ–‡å­—ä¸ø™‹±æ–‡ï¼Œ¾ŸŽå›½è§„定的计½Ž—机信息交换用的字符¾~–码集是äºÞZ»¬ç†ŸçŸ¥çš„æ‰©å±•ASCII码,它以8bit字节为单位存储,ASCIIçš?-31å?27为控制符åQ?2-126为可见字½W¦ï¼ŒåŒ…括所有的英文字母åQŒé˜¿æ‹‰ä¼¯æ•°å­—å’Œå…¶ä»–ä¸€äº›å¸¸è§ç¬¦åøP¼Œ128-255çš„ASCII码则没有定义ã€?

ASCII对英语国家是够用了,但对其他西欧国家却不够用åQŒå› æ­¤ï¼ŒäºÞZ»¬ž®†ASCII扩展åˆ?-255的范å›ß_¼Œå½¢æˆäº†ISO-8859-1å­—ç¬¦é›†ã€‚å€¼å¾—ä¸€æçš„æ˜¯ï¼Œå› äØ“è€ƒè™‘åˆ°ç¨‹åºä¸­å¤„ç†çš„ä¿¡æ¯å¤§å¤šæ˜¯è¥¿æ–‡ä¿¡æ¯åQŒå› æ­¤æœ‰äº›WEB容器åQˆå¦‚åQšTomcat4.xåQ‰åœ¨å¤„理所接收到的request字符串时åQŒå¦‚æžœæ?zh¨¨n)¨æ²¡æŒ‡å®šrequest的编码方式则¾pȝ»Ÿž®Þq¼ºçœåœ°é‡‡ç”¨ISO-8859-1åQŒæ˜Žç™½è¿™ä¸€ç‚¹å¯¹ç†è§£åŽé¢çš„问题会有帮助ã€?

相比西方的拼éŸÏx–‡å­—,东方的文字(如中文)的字½W¦æ•°è¦å¤§å¾—多åQŒæ ¹æœ¬ä¸å¯èƒ½åœ¨ä¸€ä¸ªå­—节内ž®†å®ƒä»¬è¡¨½Cºå‡ºæ¥ï¼Œå› æ­¤åQŒå®ƒä»¬ä»¥ä¸¤ä¸ªå­—节为单位存储,以中文国标字½W¦é›†GB2312ä¸ÞZ¾‹åQŒå®ƒçš„ç¬¬ä¸€ä¸ªå­—èŠ‚äØ“128-255。系¾lŸå¯ä»¥æ®æ­¤åˆ¤æ–­ï¼Œè‹¥ç¬¬ä¸€ä¸ªå­—节大äº?27åQŒåˆ™æŠŠä¸Žè¯¥å­—节后紧接着的一个字节结合è“v来共两个字节¾l„成一个中文字½W¦ã€‚è¿™¿Uç”±å¤šä¸ªå­—节存储一个字½W¦çš„字符集叫多字节字½W¦é›†åQˆMultiByte CharsetsåQ‰ï¼Œå¯¹åº”的象ASCII˜q™ç§ç”¨ä¸€ä¸ªå­—节存储一个字½W¦çš„字符集叫单字节字½W¦é›†åQˆSingleByte CharsetsåQ‰ã€‚在GB2312字符集中åQŒASCII字符仍然用一个字节存储,换句话说该ASCII是该字符集的子集ã€?

GB2312只包含数千个常用汉字åQŒå¾€å¾€ä¸èƒ½æ»¡èƒö实际需要,因此åQŒäh们对它进行扩展,˜q™å°±æœ‰äº†æˆ‘们现在òq¿æ³›ä½¿ç”¨çš„GBK字符集,GBK是现阶段Windows及其他一些中文操作系¾lŸçš„¾~ºçœå­—符集。它包含2万多个字½W¦ï¼Œé™¤äº†ä¿æŒå’ŒGB2312兼容外,˜q˜åŒ…含繁体中文字åQŒæ—¥æ–‡å­—½W¦å’Œæœé²œå­—符。值得注意的是GBK只是一个规范而不是国家标准,新的国家标准是GB18030-2000åQŒå®ƒæ˜¯æ¯”GBK包含字符更多的字½W¦é›†ã€?

我国的台湑֜°åŒÞZ‹É用的文字是繁体字åQŒå…¶å­—符集是BIG5åQŒè€Œæ—¥æœ¬é‡‡ç”¨çš„字符集则是SJIS。它们的¾~–码æ–ÒŽ(gu¨©)³•与GB2312¾cÖM¼¼åQŒå®ƒä»¬çš„ASCII字符部分是兼容的åQŒä½†æ‰©å±•部分的编码则是不兼容的,比如˜q™å‡ ¿Uå­—½W¦é›†ä¸­éƒ½æœ?中文"˜q™ä¸¤ä¸ªå­—½W¦ï¼Œä½†ä»–们在各自的字½W¦é›†ä¸­çš„¾~–码òq¶ä¸ç›¸åŒåQŒè¿™ž®±æ˜¯ç”¨GB2312写成的网™å는¨BIG5‹¹è§ˆæ—Óž¼Œçœ‹åˆ°çš„æ˜¯ä¹Þq³Ÿ¾pŸçš„信息的原因ã€?

可见åQŒåœ¨å­—符集的世界里,呈现¾l™æˆ‘们的是一个群雄割据的局面,各字½W¦é›†æ‹¥æœ‰ä¸€å—自å·Þqš„地盘。这¾l™å„国和各地åŒÞZº¤æ¢ä¿¡æ¯å¸¦æ¥äº†å¾ˆå¤§çš„困难,同时åQŒä¹Ÿ¾l™å›½é™…化åQˆæœ¬åœ°åŒ–åQ‰ç¼–½E‹é€ æˆäº†å¾ˆå¤§çš„éºÈƒ¦ã€?

常言道:"分久必合"åQŒéšç€å›½é™…标准ISO10646定义的通用字符集(Universal Character Set即UCSåQ‰çš„出现åQŒä‹É˜q™ç§å±€é¢å‘生了å½Õdº•的改观。UCS 是所有其他字½W¦é›†æ ‡å‡†çš„一个超é›? 它保证与其他字符集是双向兼容çš? ž®±æ˜¯è¯? 如果你将ä»ÖM½•文本字符串翻译到 UCS格式, 然后再翻译回原编ç ? 你不会丢å¤×ƒ“Q何信息。UCS 包含了用于表达所有已知语­a€çš„å­—½W¦ã€‚不仅包括拉丁语、希腊语ã€?斯拉夫语、希伯来语、阿拉伯语、亚¾ŸŽå°¼äºšè¯­å’Œä¹”æ²ÖMºšè¯­çš„æè¿°ã€è¿˜åŒ…括中文ã€?日文和韩文这æ ïL(f¨¥ng)š„象åŞ文字ã€?以及òq›_‡åã€ç‰‡å‡åã€?孟加拉语ã€?旁遮普语果鲁½I†å¥‡å­—符(Gurmukhi)ã€?æ³°ç±³ž®”语、印.埃纳徯‚¯­(Kannada)、Malayalam、泰国语ã€?老挝语ã€?汉语拼音(Bopomofo)、Hangulã€?Devangari、Gujarati、Oriya、Telugu 以及其他æ•îC¹Ÿæ•îC¸æ¸…的语。对于还没有加入的语­a€åQ?ç”׃ºŽæ­£åœ¨ç ”究怎样在计½Ž—机中最好地¾~–码它们åQ?因而最¾lˆå®ƒä»¬éƒ½ž®†è¢«åŠ å…¥ã€?

ISO 10646 定义了一ä¸?31 位的字符集ã€?然而, 在这巨大的编码空间中åQ?˜q„今为止只分配了å‰?65534 个码ä½?(0x0000 åˆ?0xFFFD)ã€?˜q™ä¸ª UCS çš?16位子集称ä¸?基本多语­a€é?(Basic Multilingual Plane, BMP)ã€?ž®†è¢«¾~–码åœ?16 ä½?BMP 以外的字½W¦éƒ½å±žäºŽéžå¸¸ç‰ÒŽ(gu¨©)®Šçš„å­—½W?比如象åŞ文字)åQ?且只有专家在历史和科学领域里才会用到它们ã€?

UCS 不仅¾l™æ¯ä¸ªå­—½W¦åˆ†é…ä¸€ä¸ªä»£ç ï¼Œ 而且赋予了一个正式的名字ã€?表示一ä¸?UCS 值的十六˜q›åˆ¶æ•ŽÍ¼Œ 通常在前面加ä¸?"U+", ž®Þp±¡ U+0041 代表字符"拉丁大写字母A"ã€?UCS 字符 U+0000 åˆ?U+007F ä¸?US-ASCII(ISO 646) 是一致的åQ?U+0000 åˆ?U+00FF ä¸?ISO 8859-1(Latin-1) 也是一致的。这里要注意的是它是ä»?6bit为单位存储,即便对字æ¯?A"也是ç”?6bitåQŒè¿™æ˜¯ä¸Žå‰é¢ä»‹ç»çš„æ‰€æœ‰å­—½W¦é›†ä¸åŒçš„地斏V€?

历史上,在国际标准化¾l„织研究ISO10646标准的同æ—Óž¼Œå¦ä¸€ä¸ªç”±å¤šè¯­­a€è½¯äšg刉™€ å•†¾l„成的协会也在从事创立单一字符集的工作åQŒè¿™ž®±æ˜¯çŽ°åœ¨äºÞZ»¬ç†ŸçŸ¥çš„Unicode。幸˜qçš„æ˜¯ï¼Œ1991òq´å‰åŽISO10646å’ŒUnicode的参与者都认识刎ͼŒä¸–界上不需要两个不同的单一字符集。他们合òq¶åŒæ–¹çš„工作成果åQŒåƈ为创立单一¾~–ç è¡¨è€ŒååŒå·¥ä½œã€‚ä¸¤ä¸ªé¡¹ç›®ä»éƒ½å­˜åœ¨åÆˆç‹¬ç«‹åœ°å…¬å¸ƒå„è‡ªçš„æ ‡å‡†åQŒéƒ½åŒæ„ä¿æŒISO10646å’ŒUnicode的码表兼容,òq¶ç´§å¯†åœ°å…±åŒè°ƒæ•´ä»ÖM½•未来的扩展。这与当òq´åœ¨PCæœÞZ¸Šçš„æ“ä½œç³»¾lŸMS-dos与PC-dos的情形有些相象。后面,我们ž®†è§†ISO10646å’ŒUnicode为同一个东è¥Ñ€?

有了UnicodeåQŒå­—½W¦é›†é—®é¢˜æŽ¥è¿‘了完¾ŸŽçš„解决åQŒä½†ä¸è¦é«˜å…´å¾—过早。由于历史的原因åQšä¸€äº›æ“ä½œç³»¾lŸå¦‚åQšUnix、Linux½{‰éƒ½æ˜¯åŸºäºŽASCII设计的。此外,˜q˜æœ‰ä¸€äº›æ•°æ®åº“½Ž¡ç†¾pȝ»Ÿè½¯äšg如:Oracle½{‰ä¹Ÿæ˜¯å›´¾l•ASCII来设计的(从其8i的白皮书上介¾lçš„讄¡½®¾pȝ»Ÿå­—符集和字段的字½W¦é›†ä¸­å¯ä»¥é—´æŽ¥åœ°çœ‹åˆ°˜q™ä¸€ç‚?。在˜q™äº›¾pȝ»Ÿä¸­ç›´æŽ¥ç”¨Unicode会导致严重的问题。用˜q™äº›¾~–码的字½W¦ä¸²ä¼šåŒ…含一些特ŒDŠçš„字符åQ?比如 '\0' æˆ?'/'åQ?它们åœ?æ–‡äšg名和其他 C 库函数参数里都有特别的含义ã€?另外åQ?大多æ•îC‹Éç”?ASCII æ–‡äšgçš?UNIX 下的工具åQ?如果不进行重大修æ”ÒŽ(gu¨©)˜¯æ— æ³•è¯Õd– 16 位的字符的ã€?åŸÞZºŽ˜q™äº›åŽŸå› åQ?在文件名, 文本文äšg, 环境变量½{‰åœ°æ–¹ï¼Œç›´æŽ¥ä½¿ç”¨Unicode是不合适的ã€?

åœ?ISO 10646-1 Annex R å’?RFC 2279 里定义的 UTF-8 åQˆUnicode Transformation Form 8-bit formåQ‰ç¼–码没有这些问题ã€?

UTF-8 有以下一些特性:

UCS 字符 U+0000 åˆ?U+007F (ASCII) è¢«ç¼–ç äØ“å­—èŠ‚ 0x00 åˆ?0x7F (ASCII 兼容)ã€?˜q™æ„å‘³ç€åªåŒ…å?7 ä½?ASCII 字符的文件在 ASCII å’?UTF-8 两种¾~–码方式下是一æ ïL(f¨¥ng)š„ã€?

所æœ?>U+007F çš?UCS å­—ç¬¦è¢«ç¼–ç äØ“ä¸€ä¸ªå¤šä¸ªå­—èŠ‚çš„ä¸ÔŒ¼Œ 每个字节都有标记位集ã€?å› æ­¤åQŒASCII 字节 (0x00-0x7F) 不可能作ä¸ÞZ“Q何其他字½W¦çš„一部分ã€?

表示é?ASCII 字符的多字节串的½W¬ä¸€ä¸ªå­—节æ€ÀL˜¯åœ?0xC0 åˆ?0xFD 的范围里, òq¶æŒ‡å‡ø™¿™ä¸ªå­—½W¦åŒ…含多ž®‘个字节ã€?多字节串的其余字节都åœ?0x80 åˆ?0xBF 范围里ã€?˜q™ä‹É得重新同步非常容易, òq¶ä‹É¾~–码无国界,且很ž®‘受丢失字节的媄响ã€?

UTF-8 ¾~–码字符理论上可以最多到 6 个字节长åQ?ç„¶è€?16 ä½?BMP 字符最多只用到 3 字节é•ѝ€?

字节 0xFE å’?0xFF åœ?UTF-8 ¾~–码中从未用到ã€?

通过åQŒUTF-8˜q™ç§å½¢å¼åQŒUnicode¾lˆäºŽå¯ä»¥òq¿æ³›çš„在各种情况下ä‹É用了。在讨论struts的国际化¾~–程之前åQŒæˆ‘们先来看看我们以前在jsp¾~–程中是怎样处理中文问题以及我们¾lå¸¸é‡åˆ°çš„:
二、中文字½W¦äؕ码的原因及解军_Šžæ³?/B>

java的内核是Unicode的,也就是说åQŒåœ¨½E‹åºå¤„理字符时是用Unicode来表½Cºå­—½W¦çš„åQŒä½†æ˜¯æ–‡ä»¶å’Œ‹¹çš„保存方式是ä‹É用字节流的。在java的基本数据类型中åQŒchar是Unicode的,而byte是字节,因此åQŒåœ¨ä¸åŒçš„环节java要对字节‹¹å’Œchar˜q›è¡Œè½¬æ¢ã€‚è¿™¿Uè{换发生时如果字符集的¾~–码选择不当åQŒå°±ä¼šå‡ºçŽîCؕ码问题ã€?

æˆ‘ä»¬å¸¸è§çš„äØ•ç å¤§è‡´æœ‰å¦‚ä¸‹å‡ ç§æƒ…åÅžåQ?BR>1、汉字变成了问号"åQ?
2、有的汉字显½Cºæ­£¼‹®ï¼Œæœ‰çš„则显½Cºé”™è¯?BR>3、显½CÞZؕ码(有些是汉字但òq¶ä¸æ˜¯ä½ é¢„期的)
4、读写数据库出现ä¹Þq 

下面我们逐一对它们出现的原因做一些解释:

首先åQŒæˆ‘们讨论汉字变成问åïL(f¨¥ng)š„问题ã€?

Java中byte与charç›æ€º’转换的方法在sun.io包中。其中,byte到char的常用è{换方法是åQ?BR>public static ByteToCharConverter getConverter(String encoding);

ä¸ÞZº†ä¾¿äºŽå¤§å®¶ç†è§£åQŒæˆ‘们先来做一个小实验åQšæ¯”å¦‚ï¼Œæ±‰å­—"ä½?çš„GBK¾~–码ä¸?xc4e3åQŒå…¶Unicode¾~–码是\u4f60。我们的实验是这æ ïL(f¨¥ng)š„åQŒå…ˆæœ‰ä¸€ä¸ªé¡µé¢æ¯”如名为a_gbk.jsp输入汉字"ä½?åQŒæäº¤ç»™™åµé¢b_gbk.jsp。在b_gbk.jspæ–‡äšg中以某种¾~–码方式得到"ä½?的字节数¾l„,再将该数¾l„以某种¾~–码方式转换成charåQŒå¦‚果得到的char值是0x4f60则è{换是正确的ã€?

a_gbk.jsp的代码如下:

<%@ page contentType="text/html; charset=GBK" language="java" import="java.sql.*" errorPage="" %>
<table width="611" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td>&nbsp;</td>
    <td class="bigword">&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td width="100">&nbsp;</td>
    <td class="bigword">Input</td>
    <td width="100">&nbsp;</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td class="bigword">&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
</table>
<table width="611" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td><form method="post" action="b_gbk.jsp">
        <table width="611" border="0" cellpadding="0" cellspacing="0">
          <tr>
            <td width="100" align="right"></td>
            <td><input name="ClsID" type="text" class="word" id="ClsID" maxlength="2" >
              *</td>
          </tr>
          <tr>
            <td width="100" align="right">&nbsp;</td>
            <td><input name="btn" type="submit" value="OK">
             </td>
          </tr>
        </table>
      </form></td>
  </tr>
</table>


b_gbk.jsp的代码如下:

<%@ page contentType="text/html; charset=GBK" import="sun.io.*,java.util.*" %>
<%
String a=(String)request.getParameter("ClsID");
byte b[]=a.getBytes("ISO8859-1");
for(int j=0;j<b.length;j++){
  out.println(Integer.toHexString(b[j])+"<br>");
}
ByteToCharConverter convertor=ByteToCharConverter.getConverter("GBK");
char[] c=convertor.convertAll(b);
out.println("b length:"+b.length+"<br>");
out.println("c length:"+c.length+"<br>");
for(int i=0;i<c.length;i++){
 	out.println(Integer.toHexString(c[i])+"<br>");
}
String a1=new String(a.getBytes("ISO8859-1"),"GBK");
%>
<%="a�"+a%><br>
<%="a1�"+a1%>


在浏览器中打开a_gbk.jspòq¶è¾“入一ä¸?ä½?字,点击OK按钮提交表单åQŒåˆ™ä¼šå‡ºçް如å›?所½Cºçš„¾l“æžœåQ?



å›?

从图1可以看出åQŒåœ¨b_gbk.jsp中这样将byte转换为char是正¼‹®çš„åQŒå³å¾—到的char是\u4f60。这里要注意的是åQšbyte b[]=a.getBytes("ISO8859-1");中的¾~–码是ISO8859-1åQŒè¿™ž®±æ˜¯æˆ‘们前面提到的有些web容器在æ?zh¨¨n)¨æ²¡æœ‰æŒ‡å®šrequest的字½W¦é›†æ—¶å®ƒ?y¨­u)®±é‡‡ç”¨ç¼ºçœçš„ISO8859-1ã€?

从图1中我们还看到表达å¼?%="aæ˜?"+a%>中的aòq¶æ²¡æœ‰æ­£¼‹®åœ°æ˜„¡¤º"ä½?而是变成"??"˜q™æ˜¯ä»€ä¹ˆåŽŸå› å‘¢åQŸè¿™é‡Œçš„a是作ä¸ÞZ¸€ä¸ªString被显½Cºçš„åQŒæˆ‘们来看看我们常用的String构造函敎ͼš

String(byte[] bytes,String encoding);

在国标åã^åîC¸ŠåQŒè¯¥å‡½æ•°ä¼šè®¤ä¸ºbytes是按GBK¾~–码的,如果后一个参数省略,它也会认为是encoding是GBKã€?

对前一个参数就相当于将b_gbk.jspæ–‡äšg的这句byte b[]=a.getBytes("ISO8859-1");中的ISO8859-1æ”¹äØ“GBKåQŒè¿™æ äh˜¾ç„¶åœ¨GBK字符集中找不到相应的目的¾~–码åQŒå®ƒ¾l™å‡ºçš„结果是0x3fã€?x3f。因此,ž®×ƒ¼šæ˜„¡¤ºä¸???"åQŒè¿™ä¹Ÿå°±æ˜¯é€ æˆä¹Þq çš„第一¿UçŽ°è±¡çš„åŽŸå› ã€‚æˆ‘ä»¬çš„ä¾‹å­æ˜¯æ¼”½Cºçš„从byte到charçš„è{换过½E‹ï¼Œç›¸åçš„过½E‹ä¹Ÿä¼šé€ æˆåŒæ ·çš„问题,限于½‹‡å¹…åQŒå°±ä¸åœ¨æ­¤è®¨è®ÞZº†åQŒå¤§å®¶è‡ªå·±å¯ä»¥åš¾cÖM¼¼çš„实验来验证ã€?

解决该问题的æ–ÒŽ(gu¨©)³•ž®±æ˜¯è±¡ä¾‹å­ä¸­a1那样åQŒåœ¨èŽ·å–byte数组æ—Óž¼ŒæŒ‡å®š¾~–码为ISO8859-1ã€?

接下来,我们讨论有些汉字能正常显½Cºï¼Œæœ‰äº›ä¸èƒ½æ­£å¸¸æ˜„¡¤ºçš„问题ã€?

如果我们ž®†String a1=new String(a.getBytes("ISO8859-1"),"GBK");中的GBKæ”¹äØ“GB2312则象朱镕基的"é•?字就不能正常昄¡¤ºåQŒè¿™æ˜¯å› ä¸ø™¯¥å­—是GBK中的字符而在GB2312中不存在ã€?

解决上述两种问题的方法就是象a1那样构造StringåQŒä¹Ÿž®±æ˜¯äºÞZ»¬å¸¸è¯´çš„同时也是常用的转码的方法。采用这¿Uæ–¹æ³•会在程序中到处出现˜q™ç§è¯­å¥åQŒç‰¹åˆ«æ˜¯åœ¨Struts中,Struts有一个回写表单的功能åQŒåœ¨å›žå†™æ—¶ä¹Ÿè¦åš˜q™ç§è½¬æ¢åQŒè¿™æ ïL(f¨¥ng)š„语句差不多要多一倍。因此,˜q™æ˜¯ä¸ªæ¯”较笨拙的æ–ÒŽ(gu¨©)³•åQŒæœ‰æ²¡æœ‰½Ž€æ·ä¸€äº›çš„æ–ÒŽ(gu¨©)³•呢?其实是有的,只要在取得request的字½W¦ä¸²å‰åŠ ä¸Šrequest.setCharacterEncoding("GBK");˜q™å¥åQŒæŒ‡å®šrequest的字½W¦é›†ã€‚则<%="aæ˜?"+a%>中的až®Þpƒ½æ­£å¸¸æ˜„¡¤ºåQŒa1反而不能正常显½Cºã€‚此时要ž®†byte b[]=a.getBytes("ISO8859-1");中的ISO8859-1变成GBKåQŒä»Žbyte到charçš„è{换才是正¼‹®çš„åQŒè¿™ž®±æ˜¯æ­¤æ—¶a能正常显½Cø™€Œa1反而不能正常显½Cºçš„原因。如果此时要a1正常昄¡¤ºåˆ™å¿…™åÕd°†String a1=new String(a.getBytes("ISO8859-1"),"GBK");中的ISO8859-1æ”¹äØ“GBKã€?

很显ç„Óž¼Œä½¿ç”¨request.setCharacterEncoding("GBK");只能解决GBK字符问题åQŒè¦è§£å†³i18n问题则要使用UTF-8来取代GBK。我们接着做上˜q°å®žéªŒï¼Œž®†a_gbk.jspå’Œb_gbk.jsp分别另存为a.jspå’Œb.jspž®†æ–‡ä»¶ä¸­çš„GBKæ”¹äØ“UTF-8åQŒæ›´æ”¹åŽçš„代码分别如下:

a.jsp代码åQ?

<%@ page contentType="text/html; charset=UTF-8" language="java" import="java.sql.*" errorPage="" %>

<table width="611" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td>&nbsp;</td>
    <td class="bigword">&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td width="100">&nbsp;</td>
    <td class="bigword">Input</td>
    <td width="100">&nbsp;</td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td class="bigword">&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
</table>
<table width="611" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td><form method="post" action="b.jsp">
        <table width="611" border="0" cellpadding="0" cellspacing="0">
          <tr>
            <td width="100" align="right"></td>
            <td><input name="ClsID" type="text" class="word" id="ClsID" maxlength="2" >
              *</td>
          </tr>
          <tr>
            <td width="100" align="right">&nbsp;</td>
            <td><input name="btn" type="submit" value="OK">
             </td>
          </tr>
        </table>
      </form></td>
  </tr>
</table>
b.jsp代码åQ?
<ccid_nobr>
<table width="400" border="1" cellspacing="0" cellpadding="2" 
 bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center">
<tr>
    <td bgcolor="e6e6e6" class="code" style="font-size:9pt">
    <pre><ccid_code>  <%@ page contentType="text/html; charset=UTF-8" import="sun.io.*,java.util.*" %>

<%
request.setCharacterEncoding("UTF-8");
String a=(String)request.getParameter("ClsID");
byte b[]=a.getBytes("UTF-8");
for(int j=0;j<b.length;j++){
  out.println(Integer.toHexString(b[j])+"<br>");
}
ByteToCharConverter convertor=ByteToCharConverter.getConverter("UTF-8");
char[] c=convertor.convertAll(b);
out.println("b length:"+b.length+"<br>");
out.println("c length:"+c.length+"<br>");
for(int i=0;i<c.length;i++){
  out.println(Integer.toHexString(c[i])+"<br>");
}
String a1=new String(a.getBytes("UTF-8"),"UTF-8");
%>
<%="a�"+a%><br>
<%="a1�"+a1%>


再在a.jsp中输å…?ä½?字,你会发现昄¡¤º¾l“果中,一个汉字是用三个byte表示的,它们的值分别是0xe4ã€?xbdã€?xa0åQŒä¹Ÿž®±æ˜¯è¯´ç”¨UTF-8来表½Cºæ±‰å­—,每个汉字要比GBK多占用一个byteåQŒè¿™ä¹Ÿæ˜¯ä½¿ç”¨UTF-8要多付出的一点代价吧ã€?

现在åQŒæˆ‘们讨è®ÞZ¸€ä¸‹ç¬¬ä¸‰ä¸ªé—®é¢˜åQŒå³æ˜„¡¤ºä¹Þq åQŒæœ‰äº›èŽ«åå…¶å¦™çš„æ±‰å­—òq¶ä¸æ˜¯ä½ é¢„期的结果ã€?

在上例中ž®†String a1=new String(a.getBytes("UTF-8"),"UTF-8");æ”¹äØ“String a1=new String(a.getBytes("UTF-8"),"GBK");再输å…?ä½?字,则a1会显½Cºæˆ"‹¹?"åQŒæ?zh¨¨n)¨åªè¦çœ‹ä¸€çœ?‹¹?çš„UTF-8码和GBK码就会知道其中的奥秘了ã€?

下面åQŒæˆ‘们讨è®ÞZ¸€ä¸‹æœ€åŽä¸€ä¸ªé—®é¢˜ï¼Œž®±æ˜¯è¯Õd†™æ•°æ®åº“时出现ä¹Þq ã€?

现在一些常用的数据库都支持数据库encodingåQŒä¹Ÿž®±æ˜¯è¯´åœ¨åˆ›å¾æ•°æ®åº“时可以指定它自å·Þqš„字符集设¾|®ï¼Œæ•°æ®åº“数据以指定的编码åŞ式存储。当应用½E‹åºè®‰K—®æ•°æ®åº“æ—¶åQŒåœ¨å…¥å£å’Œå‡ºå£å¤„都会有encoding转换。如果,在应用程序中字符本来已变成了ä¹Þq åQŒå½“然也ž®±æ— æ³•æ­£¼‹®åœ°è½¬æ¢ä¸ºæ•°æ®åº“的字½W¦é›†äº†ã€‚数据库的encoding可根据需要来讄¡½®åQŒæ¯”如要支持½Ž€ã€ç¹ä½“中文、日、韩、英语选GBKåQŒå¦‚果还要支持其他语­a€æœ€å¥½é€‰UTF-8ã€?/FONT>


]]>
(è½?深入剖析JSPå’ŒServlet对中文的处理˜q‡ç¨‹ http://www.aygfsteel.com/xiaomage234/articles/5741.htmlž®é©¬æ­?/dc:creator>ž®é©¬æ­?/author>Wed, 08 Jun 2005 08:33:00 GMThttp://www.aygfsteel.com/xiaomage234/articles/5741.htmlhttp://www.aygfsteel.com/xiaomage234/comments/5741.htmlhttp://www.aygfsteel.com/xiaomage234/articles/5741.html#Feedback0http://www.aygfsteel.com/xiaomage234/comments/commentRss/5741.htmlhttp://www.aygfsteel.com/xiaomage234/services/trackbacks/5741.html阅读全文

]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º º£µíÇø| ºÍË¶ÏØ| Ëɽ­Çø| ÇàÉñÏØ| ÎÞ¼«ÏØ| Óª¿ÚÊÐ| ÐÂÆ½| Æ½ÒØÏØ| °×ɳ| ¶¨°²ÏØ| ɽ¶«| ÇåÐÂÏØ| ¿ËÀ­ÂêÒÀÊÐ| ¾Ą̊ÊÐ| ¸Ê×ÎÏØ| ´óͬÊÐ| ÇåÐìÏØ| ²ÊƱ| ´ï¶û| Î÷°²ÊÐ| ÍòÄêÏØ| ÂÞÉ½ÏØ| ÒË»ÆÏØ| äųØÏØ| ¹ã·áÏØ| ¾«ºÓÏØ| ʯÊ×ÊÐ| ÄþÎäÏØ| ÐÂÔ´ÏØ| ¸ßÌÆÏØ| лͨÃÅÏØ| Â³É½ÏØ| ¡µÂÏØ| ÕÄÆ½ÊÐ| äàË®ÏØ| ÖÎÏØ¡£| ½¶ÁëÏØ| ±£Í¤| ¶õ¶û¶à˹ÊÐ| ÃÉ×ÔÏØ| ÃöÇåÏØ|