對於InputStream讀取中文亂碼,下面這段話給出了很好的解釋,以及后續編碼上的擴展。
BufferedInputStream和BufferedOutputStream是過濾流,需要使用已存在的節點來構造。
即必須先有InputStream或OutputStream,相對直接讀寫,這兩個流提供帶緩存的讀寫,提高了系統讀寫效率性能。
BufferedInputStream讀取的是字節byte,因為一個漢字占兩個字節,而當中英文混合的時候,有的字符占一個字節,有的字符占兩個字節。
所以如果直接讀字節,而數據比較長,沒有一次讀完的時候,很可能剛好讀到一個漢字的前一個字節,這樣,這個中文就成了亂碼,后面的數據因為沒有字節對齊,也都成了亂碼。
所以我們需要用BufferedReader來讀取,它讀到的是字符,所以不會讀到半個字符的情況,不會出現亂碼。
1 package com.read; 2 3 import java.io.*; 4 5 /** 6 *千字文.txt 在 classpath 用來測試 7 */ 8 public class Main { 9 10 public static void main(String[] args) { 11 12 File file = new File("千字文.txt"); 13 14 Object obj = loadFileContent(file); 15 if (obj!=null){ 16 System.out.println(obj.toString()); 17 } 18 } 19 20 /** 21 * 此方法 讀到的是字符,所以不會讀到半個字符的情況,不會出現亂碼. 22 * @param file 23 * @return 24 */ 25 public static Object readFile(File file) { 26 StringBuilder buffer = new StringBuilder(); 27 try { 28 if (!file.exists()) { 29 return null; 30 } 31 32 InputStream inputStream = new FileInputStream(file); 33 BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); 34 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream)); 35 36 while (bufferedReader.ready()) { 37 buffer.append((char) bufferedReader.read()); 38 } 39 40 bufferedReader.close(); 41 bufferedInputStream.close(); 42 inputStream.close(); 43 44 return buffer.toString(); 45 } catch (FileNotFoundException e) { 46 e.printStackTrace(); 47 return null; 48 } catch (IOException e) { 49 e.printStackTrace(); 50 return null; 51 } 52 } 53 54 /** 55 * byte字節流讀取文件時 一個漢字占2個字節 56 * 可能只能讀到半個 時長度沒有一次讀完時 字符無法對齊 57 * 出現亂碼 可能會是以上原因 58 * @param file 59 * @return 60 */ 61 public static Object loadFileContent(File file) { 62 StringBuffer buffer = new StringBuffer(); 63 try { 64 65 if (!file.exists()) { 66 return null; 67 } 68 69 InputStream inputStream = new FileInputStream(file); 70 byte[] bytes = new byte[1024]; 71 int length; 72 73 while ((length = inputStream.read(bytes)) != -1) { 74 buffer.append(new String(bytes, 0, length)); 75 } 76 77 inputStream.close(); 78 79 return buffer.toString(); 80 } catch (FileNotFoundException e) { 81 e.printStackTrace(); 82 return null; 83 } catch (IOException e) { 84 e.printStackTrace(); 85 return null; 86 } 87 } 88 }