前段时间,在学习lucene的时候,遇到了读取txt文档遇到编码错误的问题。学了几个解决方案,大部分是将文件转十六进制(可以使用UE的Ctrl+H来查看),读取开头的四个标志位来判断。可是总有些文本文件无法识别(我遇到的是部分使用UTF-8编码的文件),后来发现了JCharDet。JCharDet是mozilla(就是firefox那家)的编码识别算法的Java实现,算了,这里是官网,自己看吧。

上代码:

package com.zhyea.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import org.mozilla.intl.chardet.nsDetector;
import org.mozilla.intl.chardet.nsICharsetDetectionObserver; /**
* 借助JCharDet获取文件字符集
*
* @author robin
*
*/
public class FileCharsetDetector { /**
* 字符集名称
*/
private static String encoding; /**
* 字符集是否已检测到
*/
private static boolean found; private static nsDetector detector; private static nsICharsetDetectionObserver observer; /**
* 适应语言枚举
* @author robin
*
*/
enum Language{
Japanese(1),
Chinese(2),
SimplifiedChinese(3),
TraditionalChinese(4),
Korean(5),
DontKnow(6); private int hint; Language(int hint){
this.hint = hint;
} public int getHint(){
return this.hint;
}
} /**
* 传入一个文件(File)对象,检查文件编码
*
* @param file
* File对象实例
* @return 文件编码,若无,则返回null
* @throws FileNotFoundException
* @throws IOException
*/
public static String checkEncoding(File file) throws FileNotFoundException,
IOException {
return checkEncoding(file, getNsdetector());
} /**
* 获取文件的编码
*
* @param file
* File对象实例
* @param language
* 语言
* @return 文件编码
* @throws FileNotFoundException
* @throws IOException
*/
public static String checkEncoding(File file, Language lang)
throws FileNotFoundException, IOException {
return checkEncoding(file, new nsDetector(lang.getHint()));
} /**
* 获取文件的编码
*
* @param path
* 文件路径
* @return 文件编码,eg:UTF-8,GBK,GB2312形式,若无,则返回null
* @throws FileNotFoundException
* @throws IOException
*/
public static String checkEncoding(String path) throws FileNotFoundException,
IOException {
return checkEncoding(new File(path));
} /**
* 获取文件的编码
*
* @param path
* 文件路径
* @param language
* 语言
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public static String checkEncoding(String path, Language lang)
throws FileNotFoundException, IOException {
return checkEncoding(new File(path), lang);
} /**
* 获取文件的编码
*
* @param file
* @param det
* @return
* @throws FileNotFoundException
* @throws IOException
*/
private static String checkEncoding(File file, nsDetector detector)
throws FileNotFoundException, IOException { detector.Init(getCharsetDetectionObserver()); if (isAscii(file, detector)) {
encoding = "ASCII";
found = true;
} if (!found) {
String prob[] = detector.getProbableCharsets();
if (prob.length > 0) {
encoding = prob[0];
} else {
return null;
}
} return encoding;
} /**
* 检查文件编码类型是否是ASCII型
* @param file
* 要检查编码的文件
* @param detector
* @return
* @throws IOException
*/
private static boolean isAscii(File file, nsDetector detector) throws IOException{
BufferedInputStream input = null;
try{
input = new BufferedInputStream(new FileInputStream(file)); byte[] buffer = new byte[1024];
int hasRead;
boolean done = false;
boolean isAscii = true; while ((hasRead=input.read(buffer)) != -1) {
if (isAscii)
isAscii = detector.isAscii(buffer, hasRead);
if (!isAscii && !done)
done = detector.DoIt(buffer, hasRead, false);
} return isAscii;
}finally{
detector.DataEnd();
if(null!=input)input.close();
}
} /**
* nsDetector单例创建
* @return
*/
private static nsDetector getNsdetector(){
if(null == detector){
detector = new nsDetector();
}
return detector;
} /**
* nsICharsetDetectionObserver 单例创建
* @return
*/
private static nsICharsetDetectionObserver getCharsetDetectionObserver(){
if(null==observer){
observer = new nsICharsetDetectionObserver() {
public void Notify(String charset) {
found = true;
encoding = charset;
}
};
}
return observer;
}
}

这个还存一个问题,就是识别Unicode编码的文件,会返回windows-1252。我使用windows-1252作为编码的时候会报错。

对了,再提供一个这个jar包下载的地址,官网有时会抽风,不能访问。

下载地址:http://download.csdn.net/detail/tianxiexingyun/8286849

就这样。

借助JCharDet获取文件字符集的更多相关文章

  1. Java如何获取文件编码格式

    1:简单判断是UTF-8或不是UTF-8,因为一般除了UTF-8之外就是GBK,所以就设置默认为GBK.  按照给定的字符集存储文件时,在文件的最开头的三个字节中就有可能存储着编码信息,所以,基本的原 ...

  2. JAVA中获取文件MD5值的四种方法

    JAVA中获取文件MD5值的四种方法其实都很类似,因为核心都是通过JAVA自带的MessageDigest类来实现.获取文件MD5值主要分为三个步骤,第一步获取文件的byte信息,第二步通过Messa ...

  3. java读取resource/通过文件名获取文件类型

    java读取resource java读取resource目录下文件的方法: 借助Guava库的Resource类 Resources.getResource("test.txt" ...

  4. Atitit.检测文本文件的编码 自动获取文件的中文编码

    Atitit.检测文本文件的编码 自动获取文件的中文编码 1 不能使用load来检测编码..1 2 使用convert来检测编码1 3 程序检测文本编码2 3.1 根据utf bom头2 3.2 检测 ...

  5. C++获取文件夹中所有文件

    获取文件夹中的文件,用到过很多次,每次用的时候都要去查下,很烦,所以想自己写下,当然,借鉴了很多其他大佬的博客 主要实现的函数,如下: void getFiles( string path, vect ...

  6. 获取文件的缩略图Thumbnail和通过 AQS - Advanced Query Syntax 搜索本地文件

    演示如何获取文件的缩略图 FileSystem/ThumbnailAccess.xaml <Page x:Class="XamlDemo.FileSystem.ThumbnailAcc ...

  7. FastDFS 通过文件名获取文件信息

    /** * 获取文件信息 * * param string group_name 文件所在的组名 * param string file_id 文件id(如: M00/09/BE/rBBZolgj6O ...

  8. c# .net获取文件夹下的所有文件(多层递归),并获取区间数据(Jsion,xml等数据)写出到处理文件,学习分享~

    static void Main(string[] args)        { string path = string.Format(@"C:\Users\Administrator\D ...

  9. java 获取文件列表,并按照文件名称排序

    需求:获取全部的日志文件,并按照文件名称倒序排列,把最新的文件放在最前1.获取全部的日志文件:(方法:public List<String> ergodic(File file,List& ...

随机推荐

  1. 每日linux命令学习-xargs命令

    xargs命令 xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具.它把一个数据流分割为一些足够小的块,以方便过滤器和命令进行处理.通常情况下,xargs从管道或者stdin中读取数据 ...

  2. STM32硬件IIC (转)

    源: STM32硬件IIC

  3. spring(读取外部数据库配置信息、基于注解管理bean、DI)

    ###解析外部配置文件在resources文件夹下,新建db.properties(和数据库连接相关的信息) driverClassName=com.mysql.jdbc.Driverurl=jdbc ...

  4. mycat实现mysql数据库的垂直切分

    在我们的工作中可能会遇到数据库的io瓶颈. 这个时候我们应该怎么办呢? 解决办法有很多,我们可以想到的为:数据库集群,主从复制,读写分离,数据库负载均衡,数据库的分库,分表.接下来我们写一下,数据库的 ...

  5. selenium 模拟手机

    import time from selenium import webdriver mobileEmulation = {'deviceName': 'Galaxy S5'} options = w ...

  6. 如何使用 lsyncd 实时同步并执行 shell 命令

    修改 lsyncd 的默认配置,不直接执行rsync 进行同步,而是改用自己的脚本. binary 指定我们的脚本 vim /usr/local/lsyncd/etc/lsyncd.conf sett ...

  7. Docker学习笔记之docker volume 容器卷的那些事(二)

    预览目录 更改目录拥有者 Data Container 切换用户 参考文章 0x00 概述 如果你读了docker volume 容器卷的那些事(一),我想应该不会遇到下面这些问题的,毕竟是具有指导意 ...

  8. Sort aborted Error in MySQL Error Log

    现象 [ERROR] lines containing "Sort aborted" are present in the MySQL error log file. [Warni ...

  9. fjwc2019 D2T3 排序(堆)

    #183. 「2019冬令营提高组」排序 贴一段ppt 考虑模拟出这个算法进行k轮(即外层的i循环到k)时的序列,之后再暴力模拟零散的步. 考虑这个算法在01序列上的表现,k轮后实际上就是将最开始的不 ...

  10. wait与sleep的区别

    1.这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类. sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用了b的sleep方法,实际上还 ...