




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、 String newStr = new String(oldStr.getBytes(), "UTF-8"); java中的String類是按照unicode進行編碼的,當使用String(byte bytes, String encoding)構造字符串時,encoding所指的是bytes中的數(shù)據(jù)是按照那種方式編碼的,而不是最后產(chǎn)生的String是什么編碼方式,換句話說,是讓系統(tǒng)把bytes中的數(shù)據(jù)由encoding編碼方式轉換成unicode編碼。如果不指明,bytes的編碼方式將由jdk根據(jù)操作系統(tǒng)決定。 當我們從文件中讀數(shù)據(jù)時,最好使用InputStream方式
2、,然后采用String(byte bytes, String encoding)指明文件的編碼方式。不要使用Reader方式,因為Reader方式會自動根據(jù)jdk指明的編碼方式把文件內(nèi)容轉換成unicode 編碼。 當我們從數(shù)據(jù)庫中讀文本數(shù)據(jù)時,采用ResultSet.getBytes()方法取得字節(jié)數(shù)組,同樣采用帶編碼方式的字符串構造方法即可。 ResultSet rs; bytep bytes = rs.getBytes(); String str = new String(bytes, "gb2312"); 不要采取下面的步驟。 ResultSet rs; Strin
3、g str = rs.getString(); str = new String(str.getBytes("iso8859-1"), "gb2312"); 這種編碼轉換方式效率底。之所以這么做的原因是,ResultSet在getString()方法執(zhí)行時,默認數(shù)據(jù)庫里的數(shù)據(jù)編碼方式為 iso8859-1。系統(tǒng)會把數(shù)據(jù)依照iso8859-1的編碼方式轉換成unicode。使用str.getBytes("iso8859-1")把數(shù)據(jù)還原,然后利用new String(bytes, "gb2312")把數(shù)據(jù)從gb231
4、2轉換成unicode,中間多了好多步驟。 從HttpRequest中讀參數(shù)時,利用reqeust.setCharacterEncoding()方法設置編碼方式,讀出的內(nèi)容就是正確的了。 先說Java。 JVM里面的任何字符串資源都是Unicode,就是說,任何String類型的數(shù)據(jù)都是Unicode編碼。沒有例外。既然只有一種編碼,那么,我們可以這么說,JVM里面的String是不帶編碼的。String相當于 char。 JVM里面的 byte 數(shù)據(jù)是帶編碼的。比如,Big5,GBK,GB2312,UTF-8之類的。 一個GBK編碼的byte 轉換成 String,其實就是從GBK編碼向Un
5、icode編碼轉換。 一個String轉換成一個Big5編碼的byte,其實就是從Unicode編碼向Big5編碼轉換。 所以,Unicode是所有編碼轉換的中間介質(zhì)。所有的編碼都有一個轉換器可以轉換到Unicode,而Unicode也可以轉換到其他所有的編碼。這樣構成了一個總線結構。 比如,如果總共有10種編碼,那么只需要 10 + 10 = 20個轉換器就夠了。如果要是兩兩直接轉換,那么,需要的轉換器數(shù)量是一個組合數(shù)字,需要90個轉換器。 一個系統(tǒng)的不同部分,都有自己的編碼。比如,數(shù)據(jù)庫,文件,JVM,瀏覽器這4個部分。 在這些部分之間數(shù)據(jù)交換的地方,就會出現(xiàn)編碼問題。比如,數(shù)據(jù)庫和JVM
6、之間,文件和JVM之間,瀏覽器和JVM之間。這些問題的原理都是相通的。 編碼問題最容易處理的地方是文件和JVM之間。文件IO API帶有encoding 參數(shù),請自行查閱。 最不容易出現(xiàn)編碼問題的地方是數(shù)據(jù)庫和JVM之間。這應該是數(shù)據(jù)庫JDBC連接的基本功能。本文不專門進行討論。 最容易出問題的地方是瀏覽器和服務器JVM之間(其實,代碼里面的字符串更容易出問題,不過,我已經(jīng)事先聲明,本文不討論代碼中的字符串編碼)。下面主要討論這塊瀏覽器和服務器JVM之間的編碼問題。 我們把瀏覽器編碼叫做 Browser_Charset,把JVM編碼叫做JVM_Charset(通常等于服務器系統(tǒng)編碼)。 當瀏覽
7、器的數(shù)據(jù)過來的時候,是一個帶有Browser_Charset的byte。 如果用戶處理程序需要一個String類型的數(shù)據(jù),那么JVM會好心好意地把這個byte轉換成String。使用的轉換器是 JVM_Charset -> Unicode。 注意,如果這個時候,Browser_Charset 和 JVM_Charset并不相等。那么,這個自動轉換是錯誤的。 為了彌補這個錯誤。我們需要做兩步工作。 (1) Unicode -> JVM_Charset,把這個String 轉換回到原來的 byte。 (2) Browser_Charset -> Unicode,把這個還原的byt
8、e轉換成 String。 這個效果,和直接從HTTP Request取得byte,然后執(zhí)行 (2) Browser_Charset -> Unicode 的效果是一樣的。 如果在Request里面設置了CharacterEncoding,那么POST Data參數(shù)就不需要自己手工轉換了,web server的自動轉換就是正確的。URL的參數(shù)編碼還涉及到URL編碼,需要考慮的問題多一些,沒有這么簡單。 JVM把數(shù)據(jù)發(fā)到瀏覽器的時候。也需要考慮編碼問題。可以在Response里面設置。另外,HTML Meta Header里面也可以設置編碼,提醒Browser選擇正確編碼。 有些語言的VM或
9、者解釋器的字符串編碼可能不同。比如,Ruby。不過,編碼轉換原理都是一樣的。 That is all. JAVA字符編碼 一、概要 在JAVA應用程序特別是基于WEB的程序中,經(jīng)常遇到字符的編碼問題。為了防止出現(xiàn)亂碼,首先需要了解JAVA是如何處理字符的,這樣就可以有目的地在輸入/輸出環(huán)節(jié)中增加必要的轉碼。其次,由于各種服務器有不同的處理方式,還需要多做試驗,確保使用中不出現(xiàn)亂碼。 二、基本概念 21 JAVA中字符的表達 JAVA 中有char、byte、String這幾個概念。char 指的是一個UNICODE字符,為16位的整數(shù)。byte 是字節(jié),字符串在網(wǎng)絡傳輸或存儲前需要轉換為byt
10、e數(shù)組。在從網(wǎng)絡接收或從存儲設備讀取后需要將byte數(shù)組轉換成String。String是字符串,可以看成是由char組成的數(shù)組。String 和 char 為內(nèi)存形式,byte是網(wǎng)絡傳輸或存儲的序列化形式。 舉例: 英 String ying = “英”; char ying = ying.charAt(0); String yingHex = Integer.toHexString(ying); 82 F1 byte yingGBBytes = ying.getBytes(“GBK”); GB編碼的字節(jié)數(shù)值 D3 A2 22 編碼方式的簡介 String序列化成byte數(shù)組或反序列化時需要
11、選擇正確的編碼方式。如果編碼方式不正確,就會得到一些0x3F的值。常用的字符編碼方式有ISO8859_1、GB2312、GBK、UTF-8/UTF-16/UTF-32。 ISO8859_1用來編碼拉丁文,它由單字節(jié)(0255)組成。 GB2312、GBK用來編碼簡體中文,它有單字節(jié)和雙字節(jié)混合組成。最高位為1的字節(jié)和下一個字節(jié)構成一個漢字,最高位為0的字節(jié)是ASCII碼。 UTF-8/UTF-16/UTF-32是國際標準UNICODE的編碼方式。 用得最多的是UTF-8,主要是因為它在對拉丁文編碼時節(jié)約空間。 UNICODE值 UTF-8編碼 U-00000000 - U-0000007F:
12、0xxxxxxx U-00000080 - U-000007FF: 110xxxxx 10xxxxxx U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xx
13、xxxx 10xxxxxx 三、J2SE中相關的函數(shù) String str =”英”; /取得GB2312編碼的字節(jié) byte bytesGB2312 = str.getBytes(“GB2312”); /取得平臺缺省編碼的字節(jié)(solaris為ISO8859_1,windows為GB2312) byte bytesDefault = str.getBytes(); /用指定的編碼將字節(jié)轉換成字符串 String newStrGB = new String(bytesGB2312, “GB2312”); /用平臺缺省的編碼將字節(jié)轉換成字符串(solaris為ISO8859_1,windows為
14、GB2312) String newStrDefault = new String(bytesDefault); /用指定的編碼從字節(jié)流里面讀取字符 InputStream in = xxx; InputStreamReader reader = InputStreamReader( in, “GB2312”); char aChar = reader.read(); 四、JSP、數(shù)據(jù)庫的編碼 41 JSP中的編碼 (1) 靜態(tài)聲明: CHARSET有兩個作用: JSP文件的編碼方式:在讀取JSP文件、生成JAVA類時,源JSP文件中漢字的編碼 JSP輸出流的編碼方式:在執(zhí)行JSP時,往res
15、ponse流里面寫入數(shù)據(jù)的編碼方式 (2) 動態(tài)改變:在往response流里面寫數(shù)據(jù)前可以調(diào)用response.setContentType(),設定正確的編碼類型。 (3) 在TOMCAT中,由Request.getParameter() 得到的參數(shù),編碼方式都是ISO8859_1。所以如果在瀏覽器輸入框內(nèi)輸入一個漢字“英”,在服務器端就得到一個ISO8859_1編碼的(0x00,0xD3,0x00,0xA2)。所以通常在接收參數(shù)時轉碼: String wrongStr = response.getParameter(“name”); String correctStr = new Str
16、ing(wrongStr.getBytes(“ISO8859_1”),”GB2312”); 在最新的SERVLET規(guī)范里面,也可以在獲取參數(shù)之前執(zhí)行如下代碼: request.setCharacterEncoding(“GB2312”); 42 數(shù)據(jù)庫的編碼 (1) 數(shù)據(jù)庫使用UTF-16 如果String中是UNICODE字符,寫入讀出時不需要轉碼 (2) 數(shù)據(jù)庫使用ISO8859_1 如果String中是UNICODE字符,寫入讀出時需要轉碼 寫入:String newStr = new String(oldStr.getByte(“GB2312”), “ISO8859_1”); 讀出:S
17、tring newStr = new String(oldStr.getByte(“ISO8859_1”),”GB2312”); 五、源文件的編碼 51 資源文件 資源文件的編碼方式和編輯平臺相關。在WINDOWS平臺下編寫的資源文件,以GB2312方式編碼。在編譯時需要轉碼,以確保在各個平臺上的正確性: native2ascii ?encoding GB2312 perties 這樣從資源文件中讀出的就是正確的UNICODE字符串。 52 源文件 源文件的編碼方式和編輯平臺相關。在WINDOWS平臺下開發(fā)的源文件,以GB2312方式編碼。在編譯的時候,需要指定源文件的編碼
18、方式: javac ?encoding GB2312 JAVA編譯后生成的字節(jié)文件的編碼為UTF-8。 最新版TOMCAT4.1.18支持request.setCharacterEncoding(String enc) 資源文件轉碼成=u82f1u65afu514b 如果數(shù)據(jù)庫使用utf-16則不需要這部分轉碼 頁面上應有 轉碼?: String s = new String (request.getParameter(“name”).getBytes(“ISO8859_1”),”GB2312”); 轉碼?: String s = new String(name.get
19、Bytes(“GB2312”),”ISO8859_1”); 轉碼?: String s = new String(name.getBytes(“ISO8859_1”),” GB2312”); = JAVA內(nèi)部究竟是用的什么字符編碼呢?這個問題我也找了很久,后來在THINK IN JAVA 3rd的12章里看到一個例子出現(xiàn)了UTF-16BE,難道是它? byte utf_16be = name.getBytes("utf-16be"); printbyte(utf_16be); 結果出來了:58 02 length = 2 哈哈,I got it!不多不少兩個字節(jié),內(nèi)容也一樣
20、。果然是它。同時我在里面也看到,UNICODE的編碼還有一個LE,這里的BE,LE我想應該是bigendian和littleendian吧。 = import java.io.*; public class TestCodeIO public static void main(String args) throws Exception InputStreamReader isr = new InputStreamReader(System.in,"iso8859-1"); /Create an InputStreamReader that uses the given ch
21、arset decoder BufferedReader br = new BufferedReader (isr); String strLine = br.readLine(); br.close(); isr.close(); System.out.println(strLine); System.out.println(new String (strLine.getBytes(),"iso8859-1");/錯誤改法 /Encodes this String (strLine) into a sequence of bytes using the platform&
22、#39;s /default charset(gb2312) then constructs a new String by decoding the /specified array of bytes using the specified charset (iso8859-1) /because this String (strLine) uses the charset decoder "iso8859-1",so it can /only be encoded by "iso8859-1",cann't be encoded by the platform's default /charset "gb2312",so this line is wrong. System.out.println(new String (strLine.getBytes("iso8859-1");/正確改法 /Encodes this String (strLine) into a sequence of bytes using the named /charset (iso8859-1),then constructs a new String by decoding th
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 新建2.1萬噸年雙酚F及環(huán)氧樹脂新建項目可行性研究報告模板-立項備案
- 2025年中國增食散行業(yè)市場發(fā)展前景及發(fā)展趨勢與投資戰(zhàn)略研究報告
- 教育App的持續(xù)監(jiān)控與安全更新機制研究
- 電氣爐項目可行性研究報告
- 高三一輪復習課后習題化學考點規(guī)范練30有機化合物的結構特點與研究方法
- 折光儀器項目可行性研究報告
- 中國微功率繼電器行業(yè)發(fā)展監(jiān)測及發(fā)展趨勢預測報告
- 2025年中國漁業(yè)基地服務市場供需現(xiàn)狀及投資戰(zhàn)略研究報告
- 企業(yè)內(nèi)部智慧教育平臺的交互設計與實踐
- 2025年中國功能糖行業(yè)市場供需格局及行業(yè)前景展望報告
- 水利安全生產(chǎn)風險防控“六項機制”右江模式經(jīng)驗分享
- 幼兒科學探究能力培養(yǎng)策略研究
- 《信息技術手段在幼兒園集體教學活動中的運用研究》課題研究總報告
- 《自動控制原理》張愛民課后習題答案解析
- SYT 6587-2021 電子式井斜儀校準方法-PDF解密
- MOOC 企業(yè)文化與商業(yè)倫理-東北大學 中國大學慕課答案
- 2024年浙江紹興市高速公路運營管理有限公司招聘筆試參考題庫含答案解析
- 幸福人生養(yǎng)老專題-課件
- 感染性疾病科崗前培訓
- 山東省高考志愿規(guī)劃
- 教科版科學四年級下冊全冊單元復習教案
評論
0/150
提交評論