其他:http://www.cnblogs.com/lxzh/archive/2012/05/30/2526557.html
java采用的編碼是unicode編碼;
查看jvm的默認編碼:
可以使用System.out.println(Charset.defaultCharset());來查看jvm默認的字符集(我的mac為utf-8(java.nio.charset.CharsetICU[UTF-8]));
JVM的字符集編碼取的是操作系統默認的字符集編碼:
win xp 中文版中:一般是GBK。
win server中文版中:一般是GB18030(猜測)。
Linux 中看本地語言環境配置文件怎么設置。
java字符串使用的是unicode編碼。

public static void main(String[] args) {
System.out.println( "當前JRE:" + System.getProperty( "java.version"));
System.out.println( "當前JVM的默認字符集:" + Charset.defaultCharset());
}
}
當前JVM的默認字符集:GBK
String( byte[] bytes, String charsetName)
Java 中,字符字節轉換時,如果不提供字符集,使用默認字符集。例如,字符串和字節數組轉換時,字節流和字符流轉換時等。

1 String str = "中文"; 2 // 獲取JVM默認字符集 3 System.out.println("defaultCharset:" + Charset.defaultCharset()); 4 5 System.out.println("##字符串轉換成byte數組"); 6 byte[] defaultByteArray = str.getBytes(); 7 byte[] gbkByteArray = str.getBytes("GBK"); 8 byte[] utfByteArray = str.getBytes("UTF-8"); 9 System.out.println("defaultByteArray:" 10 + Arrays.toString(defaultByteArray)); 11 System.out.println("gbkByteArray:" + Arrays.toString(gbkByteArray)); 12 System.out.println("utfByteArray:" + Arrays.toString(utfByteArray)); 13 14 System.out.println("##byte數組轉換成字符串"); 15 String defaultStr = new String(defaultByteArray); 16 String gbkStr = new String(defaultByteArray, "GBK"); 17 String utfStr = new String(defaultByteArray, "UTF-8"); 18 System.out.println("defaultStr:" + defaultStr); 19 System.out.println("gbkStr:" + gbkStr); 20 // 因為utf-8是變長編碼,沒有跟[-42, -48, -50, -60]對應的用utf-8字符集的字符串,所以會亂碼 21 System.out.println("utfStr:" + utfStr); 22 23 System.out.println("##字節流轉化成字符流"); 24 // 文件中只有“中文”2個字,文件采用“GBK”編碼,共4個byte 25 BufferedReader defaultReader = new BufferedReader( 26 new InputStreamReader(new FileInputStream("src/encode.txt"))); 27 BufferedReader gbkReader = new BufferedReader(new InputStreamReader( 28 new FileInputStream("src/encode.txt"), "GBK")); 29 BufferedReader utfReader = new BufferedReader(new InputStreamReader( 30 new FileInputStream("src/encode.txt"), "UTF-8")); 31 System.out.println("defaultReader:" + defaultReader.readLine()); 32 System.out.println("gbkReader:" + gbkReader.readLine()); 33 System.out.println("utfReader:" + utfReader.readLine()); 34 35 System.out.println("##字符流轉化成字節流"); 36 BufferedWriter defaultWriter = new BufferedWriter( 37 new OutputStreamWriter(System.out)); 38 BufferedWriter gbkWriter = new BufferedWriter(new OutputStreamWriter( 39 System.out, "GBK")); 40 BufferedWriter utfWriter = new BufferedWriter(new OutputStreamWriter( 41 System.out, "UTF-8")); 42 System.out.print("defaultWriter:"); 43 defaultWriter.write(str); 44 // 這里不能用close()方法,否則System.out也被關閉,后續無輸出 45 defaultWriter.flush(); 46 System.out.print("\r\ngbkReader:"); 47 gbkWriter.write(str); 48 gbkWriter.flush(); 49 System.out.print("\r\nutfReader:"); 50 utfWriter.write(str); 51 utfWriter.flush();
Java
defaultCharset:GBK
##字符串轉換成byte數組
defaultByteArray:[-42, -48, -50, -60]
gbkByteArray:[-42, -48, -50, -60]
utfByteArray:[-28, -72, -83, -26, -106, -121]
##byte數組轉換成字符串
defaultStr:中文
gbkStr:中文
utfStr:????
##字節流轉化成字符流
defaultReader:中文
gbkReader:中文
utfReader:????
##字符流轉化成字節流
defaultWriter:中文
gbkReader:中文
utfReader:涓枃
Java
1 System.out.println("##文件編碼是GBK,-Dfile.encoding=\"GBK\""); 2 System.out.println("file.encoding:" 3 + System.getProperty("file.encoding")); 4 // 在不存在的目錄下創建文件,查看報錯信息 5 try { 6 new File("directory/test.txt").createNewFile(); 7 } catch (IOException e) { 8 e.printStackTrace(); 9 } 10 11 // ##文件編碼是GBK,-Dfile.encoding="UTF-8" 12 System.out.println("##文件編碼是GBK,-Dfile.encoding=\"UTF-8\""); 13 System.out.println("file.encoding:" 14 + System.getProperty("file.encoding")); 15 // 在不存在的目錄下創建文件,查看報錯信息 16 try { 17 new File("directory/test.txt").createNewFile(); 18 } catch (IOException e) { 19 e.printStackTrace(); 20 }
##文件編碼是GBK,-Dfile.encoding="GBK"
file.encoding:GBK
java.io.IOException: 系統找不到指定的路徑。
at java.io.WinNTFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:883)
at Encoding.main(Encoding.java:72)
##鏂囦歡緙栫爜鏄疓BK,-Dfile.encoding="UTF-8"
file.encoding:UTF-8
java.io.IOException: 緋葷粺鎵句笉鍒版寚瀹氱殑璺緞銆?
at java.io.WinNTFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:883)
at Encoding.main(Encoding.java:83)
通過問題解決得出結論:sun.jnu.encoding 影響文件名的創建,而 file.encoding 則影響到文件內容。
所以說,在我們使用 Java 處理中文文件的時候,如果發現文件的中文內容沒有亂碼,而文件的中文名發生亂碼,我們就應當多考慮一下 sun.jnu.encoding 和 file.encoding 的區別了。
(四)java對字符的處理
在java應用軟件中,會有多處涉及到字符集編碼,有些地方需要進行正確的設置,有些地方需要進行一定程度的處理。
3.1. getBytes(charset)
這是java字符串處理的一個標准函數,其作用是將字符串所表示的字符按照charset編碼,並以字節方式表示。注意字符串在java內存中總是按unicode編碼存儲的。比如"中文",正常情況下(即沒有錯誤的時候)存儲為"4e2d 6587",如果charset為"gbk",則被編碼為"d6d0 cec4",然后返回字節"d6 d0 ce c4"。如果charset為"utf8"則最后是"e4 b8 ad e6 96 87"。如果是"iso8859-1",則由於無法編碼,最后返回 "3f 3f"(兩個問號)。
3.2. new String(charset)
這是java字符串處理的另一個標准函數,和上一個函數的作用相反,將字節數組按照charset編碼進行組合識別,最后轉換為unicode存儲。參考上述getBytes的例子,"gbk" 和"utf8"都可以得出正確的結果"4e2d 6587",但iso8859-1最后變成了"003f 003f"(兩個問號)。
因為utf8可以用來表示/編碼所有字符,所以new String( str.getBytes( "utf8" ), "utf8" ) === str,即完全可逆。
3.3. setCharacterEncoding()
該函數用來設置http請求或者相應的編碼。
對於request,是指提交內容的編碼,指定后可以通過getParameter()則直接獲得正確的字符串,如果不指定,則默認使用iso8859-1編碼,需要進一步處理。參見下述"表單輸入"。值得注意的是在執行setCharacterEncoding()之前,不能執行任何getParameter()。java doc上說明:This method must be called prior to reading request parameters or reading input using getReader()。而且,該指定只對POST方法有效,對GET方法無效。分析原因,應該是在執行第一個getParameter()的時候,java將會按照編碼分析所有的提交內容,而后續的getParameter()不再進行分析,所以setCharacterEncoding()無效。而對於GET方法提交表單是,提交的內容在URL中,一開始就已經按照編碼分析所有的提交內容,setCharacterEncoding()自然就無效。
對於response,則是指定輸出內容的編碼,同時,該設置會傳遞給瀏覽器,告訴瀏覽器輸出內容所采用的編碼。
3.4. 處理過程
下面分析兩個有代表性的例子,說明java對編碼有關問題的處理方法。
3.4.1. 表單輸入
User input *(gbk:d6d0 cec4) browser *(gbk:d6d0 cec4) web server iso8859-1(00d6 00d 000ce 00c4) class,需要在class中進行處理:getbytes("iso8859-1")為d6 d0 ce c4,new String("gbk")為d6d0 cec4,內存中以unicode編碼則為4e2d 6587。
l 用戶輸入的編碼方式和頁面指定的編碼有關,也和用戶的操作系統有關,所以是不確定的,上例以gbk為例。
l 從browser到web server,可以在表單中指定提交內容時使用的字符集,否則會使用頁面指定的編碼。而如果在url中直接用?的方式輸入參數,則其編碼往往是操作系統本身的編碼,因為這時和頁面無關。上述仍舊以gbk編碼為例。
l Web server接收到的是字節流,默認時(getParameter)會以iso8859-1編碼處理之,結果是不正確的,所以需要進行處理。但如果預先設置了編碼(通過request. setCharacterEncoding ()),則能夠直接獲取到正確的結果。
l 在頁面中指定編碼是個好習慣,否則可能失去控制,無法指定正確的編碼。
3.4.2. 文件編譯
假設文件是gbk編碼保存的,而編譯有兩種編碼選擇:gbk或者iso8859-1,前者是中文windows的默認編碼,后者是linux的默認編碼,當然也可以在編譯時指定編碼。
Jsp *(gbk:d6d0 cec4) java file *(gbk:d6d0 cec4) compiler read uincode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4) compiler write utf(gbk: e4b8ad e69687; iso8859-1: *) compiled file unicode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4) class。所以用gbk編碼保存,而用iso8859-1編譯的結果是不正確的。
class unicode(4e2d 6587) system.out / jsp.out gbk(d6d0 cec4) os console / browser。
l 文件可以以多種編碼方式保存,中文windows下,默認為ansi/gbk。
l 編譯器讀取文件時,需要得到文件的編碼,如果未指定,則使用系統默認編碼。一般class文件,是以系統默認編碼保存的,所以編譯不會出問題,但對於jsp文件,如果在中文windows下編輯保存,而部署在英文linux下運行/編譯,則會出現問題。所以需要在jsp文件中用pageEncoding指定編碼。
l Java編譯的時候會轉換成統一的unicode編碼處理,最后保存的時候再轉換為utf編碼。
l 當系統輸出字符的時候,會按指定編碼輸出,對於中文windows下,System.out將使用gbk編碼,而對於response(瀏覽器),則使用jsp文件頭指定的contentType,或者可以直接為response指定編碼。同時,會告訴browser網頁的編碼。如果未指定,則會使用iso8859-1編碼。對於中文,應該為browser指定輸出字符串的編碼。
l browser顯示網頁的時候,首先使用response中指定的編碼(jsp文件頭指定的contentType最終也反映在response上),如果未指定,則會使用網頁中meta項指定中的contentType。