Java 正確的做字串編碼轉換
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)
可以幫助我們輕鬆的按照指定編碼讀寫檔案。
相關文章
- 萬能java字串編碼轉換工具類Java字串編碼
- ToString()字串轉換你用正確了嗎?字串
- Go 中數字轉換字串的正確姿勢Go字串
- java安全編碼指南之:lock和同步的正確使用Java
- 正確理解和使用JAVA中的字串常量池Java字串
- CAD怎麼轉換成PDF格式?CAD轉換PDF的正確方法
- 編碼轉換
- Java 浮點到字串轉換Java字串
- java工具類之編碼轉換工具類Java
- 中文字串 轉 unicode 編碼的字串字串Unicode
- URL編碼轉換
- 字元編碼轉換字元
- java中文字串漢字轉GBK編碼Java字串
- Java字串編碼介紹Java字串編碼
- Java 中 CLOB 和字串之間的轉換Java字串
- Java SimpleDateFormat處理日期與字串的轉換JavaORM字串
- java 字串與檔案相互轉換Java字串
- java安全編碼指南之:字串和編碼Java字串
- 處理日期和時區轉換:為什麼正確的 UTC 轉換很重要
- JavaScript 如何正確處理 Unicode 編碼問題!JavaScriptUnicode
- JavaScript如何正確處理Unicode編碼問題!JavaScriptUnicode
- Java實現BCD編碼與十進位制轉換Java
- Java如何將字串轉換為字元陣列?Java字串字元陣列
- 如何在Java中將字串轉換為日期Java字串
- 檢測檔案編碼,轉換檔案編碼
- 玩轉 Ceph 的正確姿勢
- 正規表示式的字串替換方法字串
- 字串大小寫轉換和字串的比較字串
- 轉換Linux 檔案編碼方式Linux
- Python 漢字區位碼、字串 相互轉換Python字串
- Java設定JSON字串引數編碼JavaJSON字串
- 編碼轉換統一防止亂碼
- 做難而正確的事,OceanBase的取捨
- 字串-大小寫轉換字串
- list與字串轉換字串
- JAVA字串轉日期或日期轉字串Java字串
- 字串-編碼字串
- 字串編碼字串編碼