最近做項目經常會遇到Java中的亂碼問題,于是就抽時間整理下出現亂碼問題的情況和如何處理,這里做了一個整理,
分析
編碼與解碼
編碼就是將字符轉為字節,解碼就是就是將字節轉換為字符。
字節流與字符流
對文件的讀寫操作都是通過字節流來實現的,即使JAVA中有字符流,但是其底層仍然使用的字節流。
亂碼問題出現
java中使用最頻繁的是字符,當我們將文件讀入內存并在控制臺顯示時(字節流--->字符流),就需要用到解碼。如果文件是UTF-8編碼,而我們解碼時錯用成GBK(如果不指定編碼,JAVA會采取系統默認編碼)來解碼,那么只能顯示亂碼。而我們寫文件時,最好指定編碼(UTF-8)。
解決方案
示例1
將字節流轉換為字符流時,我們指定編碼格式。這是我們文件也應該是gb2312編碼
1
2
3
4
5
6
7
8
9
10
11
12
|
public static String read(String filename) throws Exception { InputStream is = new FileInputStream(filename); BufferedReader in = new BufferedReader( new InputStreamReader(is, "gb2312" )); //指定編碼格式 String s; StringBuilder sb = new StringBuilder(); while ((s = in.readLine()) != null ) { sb.append(s + "\n" ); } in.close(); return sb.toString(); } |
示例2
直接通過字節流讀入,使用String轉換為字符時,指定編碼。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package com.dy.xidian; import java.io.FileInputStream; import java.io.InputStream; class BufferedInputFile { public static String read(String filename) throws Exception { @SuppressWarnings ( "resource" ) InputStream is = new FileInputStream(filename); byte [] b = new byte [ 1024 ]; is.read(b); return new String(b, "gb2312" ); } } public class MemoryInput { public static void main(String[] args) throws Exception { String filename = "E:/html/gb2312.php" ; String s = BufferedInputFile.read(filename); System.out.println(s); } } |
陷阱
I/O操作中有個FileReader類,這個類隱藏了字節流轉為字符流的細節,我們可以這樣使用。 BufferedReader in = new BufferedReader(new FileReader(filename)); 這樣,我們直接得到就是字符流了。但我們發現,我們并沒有去設置編碼,這是因為FileReader中采用了默認編碼方式。這就變得很危險了,如果其默認的編碼格式和我們文件的編碼不同,那么讀出來的數據一定是亂碼。所以我們最好采用示例中的方式來進行流的轉換。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!