Java 正確的做字串編碼轉換__字元編碼格式

來源:互聯網
上載者:User
Java 正確的做字串編碼轉換
字串的內部表示。
字串在java中統一用unicode表示( 即utf-16 LE) ,
對於 String s = "你好哦!";
如果源碼檔案是GBK編碼, 作業系統(windows)預設的環境編碼為GBK,那麼編譯時間,  JVM將 按照GBK編碼將位元組數組解析成字元,然後將字元轉換為unicode格式的位元組數組,作為內部儲存。
當列印這個字串時,JVM 根據作業系統本地的語言環境,將unicode轉換為GBK,然後作業系統將GBK格式的內容顯示出來。
 
當源碼檔案是UTF-8, 我們需要通知編譯器源碼的格式,javac -encoding utf-8 ... , 編譯時間,JVM按照utf-8 解析成字元,然後轉換為unicode格式的位元組數組, 那麼不論源碼檔案是什麼格式,同樣的字串,最後得到的unicode位元組數組是完全一致的,顯示的時候,也是轉成GBK來顯示(跟OS環境有關)
 
亂碼如何產生。 本質上都是由於 字串原本的編碼格式 與 讀取時解析用的編碼格式不一致導致的。
例如:
String s = "你好哦!";
System.out.println( new String(s.getBytes(),"UTF-8")); //錯誤,因為getBytes()預設使用GBK編碼, 而解析時使用UTF-8編碼,肯定出錯。
其中 getBytes() 是將unicode 轉換為作業系統預設的格式的位元組數組,即"你好哦"的 GBK格式,
new String (bytes, Charset) 中的charset 是指定讀取 bytes 的方式,這裡指定為UTF-8,即把bytes的內容當做UTF-8 格式對待。
如下兩種方式都會有正確的結果,因為他們的源內容編碼和解析用的編碼是一致的。
System.out.println( new String(s.getBytes(),"GBK"));
System.out.println( new String(s.getBytes("UTF-8"),"UTF-8"));
 
那麼,如何利用getBytes 和 new String() 來進行編碼轉換呢。  網上流傳著一種錯誤的方法:
GBK--> UTF-8:    new String( s.getBytes("GBK") , "UTF-8);   ,這種方式是完全錯誤的,因為getBytes 的編碼與  UTF-8 不一致,肯定是亂碼。
但是為什麼在tomcat 下,使用 new String(s.getBytes("iso-8859-1") ,"GBK") 卻可以用呢。 答案是:
tomcat 預設使用iso-8859-1編碼, 也就是說,如果原本字串是GBK的,tomcat傳輸過程中,將GBK轉成iso-8859-1了,
預設情況下,使用iso-8859-1讀取中文肯定是有問題的,那麼我們需要將iso-8859-1 再轉成GBK, 而iso-8859-1 是單位元組編碼的,
即他認為一個位元組是一個字元, 那麼這種轉換不會對原來的位元組數組做任何改變,因為位元組數組本來就是由單個位元組組成的,
如果之前用GBK編碼,那麼轉成iso-8859-1後編碼內容完全沒變, 則 s.getBytes("iso-8859-1")  實際上還是原來GBK的編碼內容
則 new String(s.getBytes("iso-8859-1") ,"GBK")  就可以正確解碼了。 所以說這是一種巧合。
 
如何正確的將GBK轉UTF-8 ? (實際上是unicode轉UTF-8)
String gbkStr = "你好哦!"; //源碼檔案是GBK格式,或者這個字串是從GBK檔案中讀取出來的, 轉換為string 變成unicode格式
//利用getBytes將unicode字串轉成UTF-8格式的位元組數組
byte[] utf8Bytes = gbkStr.getBytes("UTF-8");
//然後用utf-8 對這個位元組數組解碼成新的字串
String utf8Str = new String(utf8Bytes, "UTF-8");
簡化後就是:
unicodeToUtf8 (String s) {
return new String( s.getBytes("utf-8") , "utf-8");
}
UTF-8 轉GBK原理也是一樣
return new String( s.getBytes("GBK") , "GBK");
 
 其實核心工作都由  getBytes(charset) 做了。
getBytes 的JDK 描述:Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array.
 
另外對於讀寫檔案,
OutputStreamWriter w1 = new OutputStreamWriter(new FileOutputStream("D:\\file1.txt"),"UTF-8");
InputStreamReader( stream, charset)
可以協助我們輕鬆的按照指定編碼讀寫檔案。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.