這兩天寫了一個 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
這個屬性中獲取的。
Java’s file.encoding property on Windows platform
This property is used for the default encoding in Java, all readers and writers would default to use 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 not be changed dynamically even this property can be changed. So the conclusion is that the default encoding can’t be changed 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.
How do you open a jar file on a mac?
You can indeed launch a jar file from the command line, with the following command:
java -jar yourfile.jar
As well as this you can assign “Jar Launcher” as the default app. To use when you double-click a jar file, as follows (I don’t believe you need the developer tools installed for this):
Click once on the .jar file in the Finder and then from the menubar in the Finder select File -> Get Info”. Click on “Open with” and from the popup menu select “Other”. A file browser window will open. In this window, go to the /System/Library/CoreServices
folder and select ‘Jar Launcher’. Then make sure the “Always Open With” checkbox is checked and then click Add. Then click the “Change all” button so that any jar file will be opened automatically. Finally, close the Info window and now when you double-click any of your jar files they should run automatically.