這篇文章介紹使用java.nio.charset.CharsetDecoder自動辨識字元集方法
研究了在網路上能找到的自動辨識字元集的方法,有效的就是利用第三方類別庫jchardet。也有用cpdetector,其實也是利用jchardet。偶然發現jdk的java.nio.charset.CharsetDecoder可以用來辨識字元集。
一、原理
一般用兩種方法建構InputStreamReader:
InputStreamReader reader = new InputStreamReader(in, charsetName);
或
InputStreamReader reader = new InputStreamReader(in, charset);
如果charset不匹配,則輸出亂碼。
還有一種建構方法,就是利用CharsetDecoder:
CharsetDecoder cd = charset.newDecoder(); InputStreamReader reader = new InputStreamReader(in, cd);
這時如果不匹配,則拋出例外:
java.nio.charset.MalformedInputException: Input length = 1 at java.nio.charset.CoderResult.throwException(CoderResult.java:277) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:338) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177) ....
這樣,就可以用作字元集探測。
二、AutoCharsetReader的使用
#AutoCharsetReader是根據上述原理,參考InputStreamReader而寫成的類,繼承Reader ,可以看身為Charset自適應的InputStreamReader。
AutoCharsetReader ar= new AutoCharsetReader(in);char c = ar.read(); ...char[] cbuf = new char[2000]; ar.read(cbuf); ... BufferedReader br = new BufferedReader(ar); br.readLine(); ...
再例如Lucene建立全文索引的TextField需要Reader參數,可以直接利用這個類別:
#Field field = new TextField("content", new AutoCharsetReader(file));
讀完檔案之後,可以得到檔案的charset。注意,是讀完之後。
Charset charset = ar.charset();
三、備選字元集
因為採用多次嘗試的方法來最終確定字元集,所以要提供備選。目前程式碼提供的預設備選字元集如下:
private final static String[] _defaultCharsets = { "US-ASCII", "UTF-8", "GB2312", "BIG5", "GBK", "GB18030", "UTF-16BE", "UTF-16LE", "UTF-16", "UNICODE"};
#也提供了更改備選字元集的方法。例如:
AutoCharsetReader ar = new AutoCharsetReader(in).setCharset("ascii", "utf-8", "gbk");
先後順序會影響探測結果。例如,如果GBK在GB2312之前,則偵測結果只能是GBK,不會是GB2312,因為GBK包含GB2312。
四、只作字元集偵測
可以只用作字元集偵測:
##
charset = AutoCharsetReader.quickDetect(file.toURI().toURL(), charsets); or: charset = AutoCharsetReader.deepDetect(file.toURI().toURL(), charsets, stops);
stops參數賦值為{"utf-8", "gbk"}。為null則需全部讀完。
五、其他
為提高效率,本類別設有buffer,初選的字元集解碼失敗,不必重新讀取io 。 buffer大小預設為8192,物件建置時可以自定義buffer大小,若參數小於16,則設為16。
以上是使用java.nio.charset.CharsetDecoder自動辨識字元集方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!