1. 程式人生 > >Java| Charset.defaultCharset()和file.encoding的關係

Java| Charset.defaultCharset()和file.encoding的關係

文章目錄


一. Charset.defaultCharset()系統預設編碼字符集介紹

說明

返回此 Java 虛擬機器的預設 charset。預設 charset 在虛擬機器啟動時決定,通常根據語言環境和底層作業系統的 charset 來確定。

Charset.defaultCharset()是作業系統的編碼,可以通過虛擬機器啟動時指定屬性-Dfile.encoding=UTF-8,來更改Charset.defaultcharset().
Charset.defaultcharset()指的是jvm輸入流、輸出流預設使用的編碼/解碼方式。

規則

當我們需要指定編碼格式,可以通過JVM引數在啟動的時候進行設定-Dfile.encoding=XXX,從而不受作業系統和語言環境的影響.
獲取預設編碼格式的原始碼如下:
①當我們不手動設定JVM引數-Dfile.encoding時,系統預設字符集則取決於語言環境和底層作業系統(Windows的CMD下是GBK,Linux下則跟設定的語言環境有關)
②當我們手動設定JVM引數-Dfile.encoding=xxx

,如果xxx是不支援的字符集,則預設使用’UTF-8’編碼.

public static Charset defaultCharset() {
    if (defaultCharset == null) {
        synchronized (Charset.class) {
            String csn = AccessController.doPrivileged(
                new GetPropertyAction("file.encoding"));
            Charset cs = lookup(csn);
            if
(cs != null) defaultCharset = cs; else defaultCharset = forName("UTF-8"); } } return defaultCharset; }

注意:
看到上面說可以通過設定系統屬性file.encoding來設定預設字符集,那麼有些朋友就想通過在執行時,通過System.setProperty("file.encoding", "GBK");來動態改變字符集,雖然可以通過System.setProperty("file.encoding","GBK")修改屬性值,但僅僅是修改了file.encoding這個屬性值,並不會影響Charset.defaultCharset()。因為jvm啟動時就已經設定了Charset.defaultcharset().

作用

Charset.defaultcharset就是“作業系統編碼”它會影響java 輸入流、輸出流預設的編碼解碼。
比如在StreamEncoder解碼流中預設就是使用的Charset.defaultcharset()

示例一:

 // 設定JVM引數啟動程式: -Dfile.encoding=UTF-8

Charset.defaultCharset();// UTF-8

String s = "哈嘍YvesHe";
byte[] b = s.getBytes();// 系統預設字符集為UTF-8,等同於s.getBytes("UTF-8")
System.out.println(new String(b));// 正常,系統預設字符集UTF-8,等同於new String(b, "UTF-8")
System.out.println(new String(b, "GBK")); // 亂碼,因為b以UTF-8編碼,這裡解碼使用的是GBK

示例二:

file.encoding=utf-8,影響了Charset.defaultcharset(),從而“中”.getBytes() 3個位元組
file.encoding=GBK,影響了Charset.defaultcharset(),從而“中”.getBytes() 2個位元組
file.encoding=utf-16,影響了Charset.defaultcharset(),從而“中”.getBytes() 4個位元組

示例三:

File file = new File("UTF-8編碼");
file.createNewFile();

String charsetName = "UTF-8";
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), charsetName);
writer.write("UTF-8編碼內容");
writer.close();

OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
將輸出檔案的內容用"UTF-8"來編碼,如果第二引數預設,則預設值為Charset.defaultcharset()的值.在StreamEncoder的forOutputStreamWriter方法中可以檢視.


二. file.encoding與Charset.defaultCharset()的關係?

可以通過在JVM啟動時通過設定-Dfile.encoding=UTF-8來設定Charset.defaultCharset()的值.
注意: 僅在JVM啟動時能指定Charset.defaultCharset()的值,在執行時通過System.setProperty("file.encoding","XXX")修改屬性,僅僅是修改了file.encoding這個屬性值.


三. sun.jnu.encoding與file.encoding的區別?

sun.jnu.encoding 影響檔名的建立,file.encoding 則影響到檔案內容。

所以說,在我們使用 Java 處理中文檔案的時候,如果發現檔案的中文內容沒有亂碼,而檔案的中文名發生亂碼,我們就應當多考慮一下 sun.jnu.encoding 和 file.encoding 的區別了.
參考:http://happygiraffe.net/blog/category/uncategorized/

PS:
Java的String在記憶體中的編碼格式是Unicode,只要在記憶體中內容沒有亂碼,對其進行編碼後,採用相同的編碼格式解碼就能還原成原來的內容.

參考:
https://blog.csdn.net/wangjun5159/article/details/48154861 file.encoding與Charset.defaultCharset
http://www.cnblogs.com/lxzh/archive/2012/05/30/2526557.html java字元編碼轉換研究