二 Java 編碼那些事

建議先閱讀:Java 編碼那些事(一)
現在說說編碼在Java中的實際運用 。在使用tomcat的時候 , 絕大部分同學都會遇到亂碼的問題,查查文檔,google一下解決方案啥的,都是設置這里,設置那里 , 或者在代碼中添加編碼方式,雖然最終問題解決了 , 但是你真的知道這是什么意思么?
在平時開發Java的時候,我們會遇到很多編碼設置,其中包括:

  • Java文件的編碼:Java文件的編碼表示編寫代碼得時候,.java文件本身的編碼,這個編碼的影響在于將你的寫的代碼源文件復制一份,使用其他編輯器打開 , 若兩個編輯器的默認編碼方式不一樣 , 則打開源文件就會變成亂碼 。一般英文的影響不大,因為大多數編碼都兼容ASCII編碼,但是中文要是編碼不正確,則會亂碼 。
    IDEA的設置在:Setting->Editor->File Encodings中設置
  • JVM編碼:JVM編碼表示JVM在讀取String類型的默認編碼 , 可以使用Charset.defaultCharset().name() 獲取 。可以在JVM啟動參數中使用-Dfile.encoding=UTF-8進行設置 。
一般需要區分的就是這兩種編碼 。下面著重說下JVM編碼的體現 。
字節流與字符流熟悉IO的同學應該都明白這兩個流的區別 。一般會出現字符亂碼都在于需要與其他程序進行IO的時候 。
先看看使用字節流進行讀取文件的時候:
public static void main(String[] args){String path="G:\\test.txt";try(BufferedInputStream inputStream=new BufferedInputStream(new FileInputStream(path))) {for (byte bytes[] = new byte[1024]; inputStream.read(bytes) != -1; ) {String context = new String(bytes);System.out.println(context);}}catch (IOException e){e.printStackTrace();}}然后再G盤新建一個文本文件,輸入一段文字 。使用默認的格式保存 。
可以查看輸出:
??????????                                                                         亂碼了,下面來分析一下:
首先這里是JVM運行時的編碼,因此和JVM的編碼設置有關 。打印JVM目前的編碼設置:
System.out.println(Charset.defaultCharset().name());輸出:UTF-8找到剛剛新建的文件test.txt,點擊另存為,可以發現默認編碼為ANSI,前一篇文章中說過,ANSI作為windows系統中的特殊存在,它在簡體中文編碼的情況下默認為GBK編碼 。這便是亂碼的原因,解決方案有兩種:
  1. 設置JVM啟動項:-Dfile.encoding = GB2312
  2. 在編碼byte數組的時候,指定GB2312編碼:String context = new String(bytes,"GB2312");
這里推薦第二種,畢竟UTF8更加通用
問題完美解決 。
同理,網絡IO也能通過以上方法解決 。
看明白了上面的發現問題和解決問題的流程的同學,下次遇到文件編碼的問題,相信應該能夠獨立解決問題 。
實戰明白了各種編碼問題,現在我們可以著手進行實戰 。
第一次使用IDEA開發Servlet的時候,大多數都會遇見亂碼問題 , 包括:
  • 控制臺輸出Tomcat日志亂碼
  • 網頁顯示Servlet返回的中文亂碼
雖然各種Google后 , 終于解決了 , 但是可能依然不明白其中的緣由 。下面我們來一探究竟
Tomcat日志首先解決Tomcat日志亂碼的問題,首先要明白:Tomcat作為一個獨立的進程,IDEA是怎么獲取到Tomcat日志的呢?在IDEA控制臺中的Tomcat啟動日志中,我們可以找到一個日志記錄:
 -Dcatalina.base=C:\xxx\.IntelliJIdea2018.3\system\tomcat\xxx復制選項中的路徑,在文件夾中打開 , 進入logs文件夾,就可以發現這個是tomcat的日志文件輸出路徑,而IDEA正是讀取了這個文件中的內容輸出到控制臺中,我們可以使用記事本打開日志文件,然后選擇另存為 , 可以發現文件的默認編碼是ANSI,也就說在簡體中文下是GBK編碼 。

推薦閱讀