利用java.nio.charset.CharsetDecoder自动识别字符集
来源:互联网 发布:win10那些软件无用 编辑:程序博客网 时间:2024/06/05 11:03
研究了在网上能找到的自动识别字符集的办法,有效的就是利用第三方类库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);
quickDetect只读一个字符,适用于单字符集文件。对于html,可能需要全部读完才知道charset,则使用deepDetect。其中参数charsets可以为null。
如果一组文件,已知可能的字符集有“ascii”,“utf-8”,“gb2312”,和“gbk”,当检测得知一个文件的字符集为“utf-8”或"gbk"的时候,可以马上返回结果,无需继续读文件。这时可以把stops参数赋值为{"utf-8", "gbk"}。为null则需全部读完。
五、其他
为提高效率,本类设有buffer,初选的字符集解码失败,不必重新读取io。buffer大小默认为8192,对象构建时可以自定义buffer大小,若参数小于16,则设为16。
六、源代码
http://download.csdn.net/detail/u012994553/9777709
- 利用java.nio.charset.CharsetDecoder自动识别字符集
- 利用java.nio.charset.CharsetDecoder自动识别字符集
- 利用java.nio.charset.CharsetDecoder自动识别字符集
- 利用java.nio.charset.CharsetDecoder自动识别字符集
- 利用java.nio.charset.CharsetDecoder自动识别字符集
- 利用java.nio.charset.CharsetDecoder自动识别字符集
- java NIO之Channel 通道 Charset字符集的使用
- [疯狂Java]NIO:使用Channel、Charset(字符集)、使用Charset传递CharBuffer
- Java]NIO:使用Channel、Charset(字符集)、使用Charset传递CharBuffer
- Java-Charset(字符集)
- Java-Charset(字符集)
- Java NIO--Charset
- CharsetDecoder.decode()与Charset.decode()
- Java nio 学习笔记(二) Charset(字符集)与Selector(异步IO)的知识
- Java nio 学习笔记(二) Charset(字符集)与Selector(异步IO)的知识
- java NIO入门简介 Charset(字符集)与Selector(异步IO)的知识
- Java nio 学习笔记(二) Charset(字符集)与Selector(异步IO)的知识
- Java nio 学习笔记(二) Charset(字符集)与Selector(异步IO)的知识
- redis 使用记录 亲试
- [机器学习]基于python的机器学习库Sklearn-01
- centos 安装 pip、pandas、numpy、scipy、scikit-learn
- 接口和抽象类的区别
- 2017移动市场的幸运与挑战,APP测试仍是不可或缺环节
- 利用java.nio.charset.CharsetDecoder自动识别字符集
- 炼数成金《机器学习》系列01
- 实现队列---数据结构和算法
- 如何合理地估算线程池大小?
- 安卓6.0+动态权限申请
- 【转载】透视“专利恶霸”系列之三 2017年,专利恶霸的中国行动元年
- HIBERNATE与 MYBATIS的对比
- 即时通讯基础
- windows nginx+tomcat+sqlserver+redis 坑+条件