java中的編碼和編碼格式問題


看來問的人和回答的人都不一定清楚什么是“編碼和編碼格式”,以及如何理解“java中字符串的編碼”;
首先明確幾點:

  1. unicode是一種“編碼”,所謂編碼就是一個編號(數字)到字符的一種映射關系,就僅僅是一種一對一的映射而已,可以理解成一個很大的對應表格
  2. GBK、UTF-8是一種“編碼格式”,是用來序列化或存儲1中提到的那個“編號(數字)”的一種“格式”;GBK和UTF-8都是用來序列化或存儲unicode編碼的數據的,但是分別是2種不同的格式; 他們倆除了格式不一樣之外,他們所關心的unicode編碼范圍也不一樣,utf-8考慮了很多種不同國家的字符,涵蓋整個unicode碼表,所以其存儲一個字符的編碼的時候,使用的字節長度也從1字節到4字節不等;而GBK只考慮中文——在unicode中的一小部分——的字符,的編碼,所以它算好了只要2個字節就能涵蓋到絕大多數常用中文(2個字節能表示6w多種字符),所以它存儲一個字符的時候,所用的字節長度是固定的;
  3. 上述2個概念不懂的請馬上google,下面不再贅述;我下面說說這個問題本身...的問題在哪里
  4. 首先java的string使用的編碼是unicode,但是,當string存在於內存中時(也就是當程序運行時、你在代碼中用string類型的引用對它進行操作時、也就是string沒有被存在文件中且也沒有在網絡中傳輸(序列化)時),是“只有編碼而沒有編碼格式的”,所以java程序中的任何String對象,說它是gbk還是utf-8都是錯的,gbk和utf-8是編碼格式而不是編碼,String在內存中不需要“編碼格式”(記住編碼格式是在存文件或序列化的時候使用的), 它只是一個unicode的字符串而已
  5. 所以java里面String是不帶編碼格式的,而String.toByteArray(charsetName)得到的byteArray是帶編碼格式的,格式就是你傳入的'charsetName',我們不妨把toByteArray的這個過程叫做“編碼”;另外,new String(byte[], charsetName)是把一個byte數組(帶編碼格式)以charsetName指定的編碼格式翻譯為一個不帶編碼格式的String對象,我們不妨把這個過程叫“解碼”
  6. 那么根據我揣測提問者的意圖,可能有2種問法是他真正想問的:
  7. 第一,如何把一個被錯誤地當作是gbk格式存儲的utf-8格式的文件里面讀出來的一段亂碼字符串還原回去(也就是說本來二進制數據是utf-8的,你用gbk來解碼它,得到的字符串是亂碼,現在想要還原回去)
  8. 第二種,如何把一個gbk文件轉化為utf-8文件
  9. 如果是第一種意圖那就:

public static void main(String... args) throws Throwable {
String errStr = "errStr";
System.out.println(recover(errStr));
}

public static String recover(String str) throws Throwable {
return new String(str.getBytes("GBK"), "UTF-8");
}
其中errStr就是亂碼字符串,按照相反的順序在編碼(用gbk)、解碼(用utf-8)回去,就能得到正確的字符串(其實不保證所有情況均能正確還原,只能說大部分都能,要看你在亂碼過程中是否有數據被丟失)

如果是第二種意圖,那就用InputStream以gbk格式將文件讀到內存里(表示為String),再將這個String以UTF-8編碼寫入目標文件里,具體請參考InputStream/OutputStream的api 

(轉自:http://www.zhihu.com/question/20361462/answer/14899233)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM