• 技术文章 >Java >java教程

    使用java.nio.charset.CharsetDecoder自动识别字符集方法

    高洛峰高洛峰2017-03-12 09:43:23原创1087
    这篇文章介绍使用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);

    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。

    以上就是使用java.nio.charset.CharsetDecoder自动识别字符集方法的详细内容,更多请关注php中文网其它相关文章!

    声明:本文原创发布php中文网,转载请注明出处,感谢您的尊重!如有疑问,请联系admin@php.cn处理
    专题推荐:java
    上一篇:分析spring web启动时IOC源码 下一篇:JAVA类与对象(实例变量与类变量的区别)(实例方法和类方法的区别 )说明
    大前端线上培训班

    相关文章推荐

    • 理解java8中java.util.function.*pojo反射新方法(附代码)• 浅析安卓app和微信授权登录及分享完整对接(代码分享)• 教你一招搞定时序数据库在Spring Boot中的使用• 一招教你使用java快速创建Map(代码分享)• PlayFramework 完整实现一个APP(十一)

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网