java 中file.encoding的設(shè)置詳解
昨天有人在討論關(guān)于設(shè)置System的property,file.encoding 修改defaultcharset無效
1
2
|
Properties pps=System.getProperties(); pps.setProperty( "file.encoding" , "ISO-8859-1" ); |
在java中,如果沒有指定charset的時(shí)候,比如new String(byte[] bytes),都會(huì)調(diào)用Charset.defaultCharset()的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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是只能被初始化一次,這里還是有點(diǎn)小問題的,在多線程并發(fā)調(diào)用的時(shí)候還是會(huì)初始話多次,當(dāng)然后面都是從cache(lookup的函數(shù))里讀出來的,問題也不大。
當(dāng)我們?cè)诟淖僑ystem.getProperties里的file.encoding 的時(shí)候,defaultCharset已經(jīng)被初始化過了,所以不會(huì)在調(diào)用初始話的代碼。
當(dāng)jvm 啟動(dòng)的時(shí)候,load class, 最后調(diào)用main函數(shù)之前,defaultCharset已經(jīng)初始化好,而很多函數(shù)里都掉用了這個(gè)方法象String.getBytes, 還有 InputStreamReader, InputStreamWriter 都是調(diào)用了 Charset.defaultCharset()的方法,就不去追查誰(shuí)先調(diào)用了defaultCharset。
對(duì)defaultCharset,在jvm里的語(yǔ)言就是初始話在啟動(dòng)的時(shí)候,而且不可被更改,你只能修改系統(tǒng)的charset,或者jvm的啟動(dòng)參數(shù)里加上 -Dfile.encoding="UTF-8"
題外話
在Java里面String是使用char數(shù)組來表示,而java的char和c的char是不同的,java的char是雙字節(jié)的, 而c 里面的char單字節(jié),等同于Java byte
也就是說我們?cè)谵D(zhuǎn)化byte 到string的時(shí)候,是根據(jù)charset decode轉(zhuǎn)化成char, 而我們?cè)谡{(diào)用println,write string的時(shí)候,還是要把char最后encode成byte 輸出到控制臺(tái),或者文件中。
而在最后調(diào)用c函數(shù)write 的時(shí)候,如果是java 的byte數(shù)組,還要轉(zhuǎn)化成c 里的char數(shù)組
1
|
(*env)->GetByteArrayRegion(env, bytes, off, len, (jbyte *)buf); |
感謝閱讀,希望能幫助到大家,謝謝大家,對(duì)本站的支持!
原文鏈接:http://blog.csdn.net/raintungli/article/details/6651076