您好,登錄后才能下訂單哦!
java 中file.encoding的設置詳解
昨天有人在討論關于設置System的property,file.encoding 修改defaultcharset無效
Properties pps=System.getProperties(); pps.setProperty("file.encoding","ISO-8859-1");
在java中,如果沒有指定charset的時候,比如new String(byte[] bytes),都會調用Charset.defaultCharset()的方法
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; }
我們可以清楚的看到defaultCharset是只能被初始化一次,這里還是有點小問題的,在多線程并發調用的時候還是會初始話多次,當然后面都是從cache(lookup的函數)里讀出來的,問題也不大。
當我們在改變System.getProperties里的file.encoding 的時候,defaultCharset已經被初始化過了,所以不會在調用初始話的代碼。
當jvm 啟動的時候,load class, 最后調用main函數之前,defaultCharset已經初始化好,而很多函數里都掉用了這個方法象String.getBytes, 還有 InputStreamReader, InputStreamWriter 都是調用了 Charset.defaultCharset()的方法,就不去追查誰先調用了defaultCharset。
對defaultCharset,在jvm里的語言就是初始話在啟動的時候,而且不可被更改,你只能修改系統的charset,或者jvm的啟動參數里加上 -Dfile.encoding="UTF-8"
題外話
在Java里面String是使用char數組來表示,而java的char和c的char是不同的,java的char是雙字節的, 而c 里面的char單字節,等同于Java byte
也就是說我們在轉化byte 到string的時候,是根據charset decode轉化成char, 而我們在調用println,write string的時候,還是要把char最后encode成byte 輸出到控制臺,或者文件中。
而在最后調用c函數write 的時候,如果是java 的byte數組,還要轉化成c 里的char數組
(*env)->GetByteArrayRegion(env, bytes, off, len, (jbyte *)buf);
感謝閱讀,希望能幫助到大家,謝謝大家,對本站的支持!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。