1. 程式人生 > >eclipse 預設UTF-8 -Dfile.encoding=UTF-8

eclipse 預設UTF-8 -Dfile.encoding=UTF-8

問題描述:
程式涉及到國際化問題,httpclient抓回來的資料亂七八糟的亂碼,在轉了幾次編碼之後在Myeclipse下可以獲取正常編碼的原始碼(準確的說是能顯示一大部分,少部分內容依然亂碼),但是將程式移植到eclipse下先前的程式就出現了亂碼(移植工作曾經嘗試過以下幾種形式:1,程式從myeclipse中匯出,然後再從Eclipse中匯入;2,將Eclipse工作空間切換到myeclipse工作空間。然後將工程編碼設定為utf-8)。如果將myeclipse工程使用fatjar打包為可執行jar包,然後在windows下執行的話還是亂碼。而在Linux環境下是正常的。
在Linux上執行定時任務的時候出現亂碼(最早的時候系統為預設的環境,安裝好的系統沒有對環境設定進行修改,這時候程式執行良好,當安裝了一些涉及到語言之類的包以後,程式異常)。
問題分析:
Myeclipse、Eclipse中的工程編碼都是utf-8
windows環境編碼GBK、Linux環境下沒有出現異常時預設編碼是utf8、異常時雖然 系統環境顯示utf-8,但是因為安裝了一些涉及系統環境的包之後,對編碼為utf-8有些 許懷疑
程式中轉換的最終編碼utf-8
懷疑物件是程式執行環境的預設編碼問題
在使用java自帶工具Java virtualVM分析程式記憶體、執行緒使用情況時,意外發現JVM arguments一項中的引數對在Eclipse和myeclipse下執行程式有所不同:Eclipse裡面得引數只有-Xmx1024m而myeclipse下的程式則多出一項:-Dfile.encoding=UTF-8
在啟動程式時多加上-Dfile.encoding=UTF-8引數,程式Eclipse中亂碼消失,Linux下定時任務執行的程式也沒有亂碼了

-Dfile.encoding解釋:
在命令列中輸入java,在給出的提示中會出現-D的說明:
-D=
               set a system property
-D後面需要跟一個鍵值對,作用是設定一項系統屬性
對-Dfile.encoding=UTF-8來說就是設定系統屬性file.encoding為UTF-8
那麼file.encoding什麼意思?字面意思為檔案編碼。
搜尋java原始碼,只能找到4個檔案中包含file.encoding的檔案,也就是說只有四個檔案呼叫了file.encoding這個屬性。
在java.nio.charset包中的Charset.java中。這段話的意思說的很明確了,簡單說就是預設字符集是在java虛擬機器啟動時決定的,依賴於java虛擬機器所在的作業系統的區域以及字符集。
程式碼中可以看到,預設字符集就是從file.encoding這個屬性中獲取的。個人感覺這個是最重要的一個因素。下面的三個可以看看。
/**
     * Returns the default charset of this Java virtual machine.
     *
     *

The default charset is determined during virtual-machine startup and
     * typically depends upon the locale and charset of the underlying
     * operating system.
     *
     * @return A charset object for the default charset
     *
     * @since 1.5
     */
    public static Charset defaultCharset() {
        if (defaultCharset == null) {
     synchronized (Charset.class) {
   java.security.PrivilegedAction pa =
      new GetPropertyAction("file.encoding");
   String csn = (String)AccessController.doPrivileged(pa);
   Charset cs = lookup(csn);
   if (cs != null)
      defaultCharset = cs;
                else 
      defaultCharset = forName("UTF-8");
            }
}
return defaultCharset;
}

在java.net包中的URLEncoder.java中的static塊裡面:
dfltEncName = (String)AccessController.doPrivileged (
      new GetPropertyAction("file.encoding")
     );
在javax.print包中的DocFlavor.java
static {
   hostEncoding = 
      (String)java.security.AccessController.doPrivileged(
                   new sun.security.action.GetPropertyAction("file.encoding"));
     }
在com.sun.org.apache.xml.internal.serializer包中的Encodings
// Get the default system character encoding. This may be
                 // incorrect if they passed in a writer, but right now there
                 // seems to be no way to get the encoding from a writer.
                 encoding = System.getProperty("file.encoding", "UTF8");

另外另一個網友的部落格上面看到的:

http://yaojingguo.blogspot.com/2009/02/javas-fileencoding-property-on-windows.html
Java's file.encoding property on Windows platfor 
This property is used for the default encoding in Java, all readers and writers would default to using this property. file.encoding is set to the default locale of Windows operationg system since Java 1.4.2. System.getProperty("file.encoding") can be used to access this property. Code such as System.setProperty("file.encoding", "UTF-8") can be used to change this property. However, the default encoding can be not changed dynamically even this property can be changed. So the conclusion is that the default encoding can't change after JVM starts. java -dfile.encoding=UTF-8 can be used to set the default encoding when starting a JVM. I have searched for this option Java official documentation. But I can't find it.