Java -Dfile.encoding=UTF-8 遭遇亂碼

Java -Dfile.encoding=UTF-8 遭遇亂碼問題的來龍去脈
這兩天寫了一個 Java 程序來玩,結果又遭遇了以前遇到過很多次的亂碼問題,具體描述一下:
在 Mac 系統裏面,常用的 Java 程序啓動方式有如下幾種:
1.通過 eclipse 執行 class 入口文件啓動;
2.在 Terminal 裏面用 java Test.class 或 jave -jar Test.jar 啓動
3.通過 ant 執行 class 入口文件啓動;
4.直接用 ant 執行 jar 文件;
5.用 Mac OS CoreServices 中的 Jar Launcher.app 執行 jar 文件。
6.用 Mac OS 自帶的 Jar Bundler.app 將 jar 文件包裝成 app,然後執行

執行途徑還是相當地豐富,但以不同的方式來執行,從控制檯中得到的程序輸出也不一致
比如說,剛剛在 eclipse 中還能正常打印出來的漢字,在打成 jar 包以後,
雙擊該 jar 文件以 Jar Launcher.app 的方式來啓動,打印出來的文字就成了亂碼了。
畢竟寫出來的 java 程序最終還是要打成 Jar 包來使用的,總不能每次都在 eclipse 中啓動吧?
前面說過,不是第一次碰到這種問題了,於是便想着要把這個問題給解決下。
靈機一動之下想到一個好辦法,在這些啓動方式下均把 System 中的屬性遍歷打印出來,
然後用 git 來做各個版本的差異比較,有可能會套出一些蛛絲馬跡~
抱着試一試的想法實踐了一把,果然發現一些貓膩,集中體現在 file.encoding 這個屬性上面。
在 file.encoding 屬性的值是 UTF-8 時,是不存在亂碼問題的,eclipse 執行就屬於這種情況。
Jar Launcher.app 執行時,該屬性的值就變成 MacRoman 了,
上面給出的資料中有對該屬性的介紹,可以用 java -D= Test.jar 來更改它。
另外,只有在啓動 java 程序前通過傳遞參數來更改纔有效,程序一經啓動就無法再更改了。
這樣的話,也就只有通過傳遞 jvm 參數的方式來做默認編碼的變更了:
其一,寫一個帶 -Dfile.encoding=UTF-8 參數的腳本文件來啓動;
其二,用 Jar Bundler.app 打包成 app,效率應該不如第一種方案。
原理其實都差不多,都只是將更改 jvm 默認編碼的操作封裝了起來,執行時就不用再手動鍵入了。

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

-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 這個屬性中獲取的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章