java 亂碼問題-Dfile.encoding=UTF-8


http://blog.csdn.net/telnetor/article/details/5555361

問題描述:
程序涉及到國際化問題,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.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM