最近的这个项目中需要对文件的编码格式进行处理,并统一转换为UTF-8格式,所以对文件的编码格式进行了一些探讨,但是在探讨的过程中发现使用java来处理文件的编码格式确实是一件比较头疼的问题,因为不能完全的获取到正确的编码格式,因为一部分文件具有头文件,我们可以根据这些头文件来判断文件格式,但是另一部分却是不存在头文件的,这样的话可能会导致获取文件格式出错,之前我们就是使用的文件头去判断的文件格式,代码如下:
public String getCharset(File file) {
String charset = "GBK";
byte[] first3Bytes = new byte[3];
boolean checked = false;
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(
new FileInputStream(file));
bis.mark(0);
int read = bis.read(first3Bytes, 0, 3);
if (read == -1)
return charset;
if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) {
charset = "UTF-16LE";
checked = true;
} else if (first3Bytes[0] == (byte) 0xFE
&& first3Bytes[1] == (byte) 0xFF) {
charset = "UTF-16BE";
checked = true;
} else if (first3Bytes[0] == (byte) 0xEF
&& first3Bytes[1] == (byte) 0xBB
&& first3Bytes[2] == (byte) 0xBF) {
charset = this.encode_utf8;
checked = true;
}
bis.reset();
if (!checked) {
// int len = 0;
int loc = 0;
while ((read = bis.read()) != -1) {
loc++;
if (read >= 0xF0)
break;
if (0x80 <= read && read <= 0xBF) // 单独出现BF以下的,也算是GBK
break;
if (0xC0 <= read && read <= 0xDF) {
read = bis.read();
if (0x80 <= read && read <= 0xBF) // 双字节 (0xC0 - 0xDF)
// (0x80
// - 0xBF),也可能在GB编码内
continue;
else
break;
} else if (0xE0 <= read && read <= 0xEF) {// 也有可能出错,但是几率较小
read = bis.read();
if (0x80 <= read && read <= 0xBF) {
read = bis.read();
if (0x80 <= read && read <= 0xBF) {
charset = this.encode_utf8;
break;
} else
break;
} else
break;
}
}
}
} catch (Exception e) {
log.error("Obtaining file format failed",e);//获取文件格式失败
} finally {
try {
if (null != bis) {
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return charset;
}
但是遇到不是UTF-8格式的就不能处理了,而且当遇到没有BOM头的utf-8的时候也无法解决,且担心当没有头文件的文件的前几个字节与问价一致的时候,可能会判断错误问价的格式,后来我使用了网上所说的第三方包:cpdetector_1.0.7.jar,使用了这个第三方包,代码如下
CodepageDetectorProxy detector = CodepageDetectorProxy.getInstance();
detector.add(new ParsingDetector(false));
detector.add(JChardetFacade.getInstance());
detector.add(ASCIIDetector.getInstance());
detector.add(UnicodeDetector.getInstance());
Charset charset = null;
try {
charset = detector.detectCodepage(file.toURI().toURL());
} catch (Exception ex) {
log.error("Carest File error!");
}
过了一段时间之后就发现问题了,使用这个后不但获取文件格式的时间超长(特别对比较大的文件来说),而且对于Unicode的编码格式也不是很支持,只要汉字中出现了"的都"等汉子之后解析的文件格式就完全错误,导致乱码了.而且时间太长导致了性能测试完全过不了,最后经过商讨订下了另一个方案,因为系统是部署在Liunx系统上的,所以决定使用liunx系统的file命令,这样时间不但比较短,且也比较准备,虽然不能完全解析所有的文件格式,但是文本文档的默认的4种已经完全能够支持了,当然如果使用了Editplus或者UE等高级浏览器,然后另存为一些格式也是无法解析的,所以这个是很痛苦的,不过已经能够支持文本编辑器的四种也满足了我们要求了,使用liunx系统命令操作如下
String command = "file " + file.getAbsolutePath();
Process proc = Runtime.getRuntime().exec(command);
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String code = br.readLine();
不过liunx系统也不是能获得所有的编码格式的,当你文件内容以&开头它可能也会解析错误的,这个的话可能要想想其他办法了,不过我们项目中的内容是绝对不会以&开头的.所以没有什么问题.
以上就是我在处理java获取文件编码格式所遇到的问题,还是要感慨一下java对文件编码格式的支持确实有点伤啊,
不过在这里还遇到可一个问题,就是取出文件的第一行数据然后判断是否为纯数字,然后我当然使用的是正则表达式的,不过这里却遇到一个问题,就是无论怎么验证一直是false,后来追了很久的代码才发现,原来正则表达式也是按照二进制的ascii嘛去匹配的,但是取出文本的第一行却发现String 的getBytes之后却获取到了它的头文件,也就是前三个字节全是负数,这个只去掉前三个字节再判断就OK了,还有使用file命令判断文件格式的话,如果是windows传上去的文件名中拥有空格这些,回导致你的命令执行不正确,因为linux上空格需要使用/转义,建议你们上传后修改为没有特殊字符的文件名.
这些就是在项目中的编码格式所遇到的困难和处理困难,如果有更好的处理方法的朋友,欢迎你告诉我,谢谢.
当然我也附上了第三方包所需要的的jar包,需要的朋友可以下载
分享到:
相关推荐
利用第三方开源包cpdetector获取文件编码格式
java 识别文件的编码格式 读取文件的编码 utf-8 gbk gb2312 java 编码 java 获取文件编码格式 java 乱码查找
通过webview打开html文件有可能编码不同就会乱码,所以要获取html文件的编码格式动态改变webview编码设置
NULL 博文链接:https://summerbell.iteye.com/blog/543318
java获取文件原始编码,
如果很多时候我们没有约定好文件格式,我们就难以读取文件内容,此时,我们就需要一个工具来探测所读文本的编码格式,此工具可以允许用户读取诸如utf-8,gbk,gb2312一类的文件格式。内置了一些常用的探测实现类,...
java工具jar文件 获取文件的编码格式 例如UTF-8,GBK,UTF-16,GB2312等等
主要介绍了详解Java如何获取文件编码格式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
本工程用于研究如何使用Java代码获取文件、文件流或字符串的编码方式 本工程编码方式:UTF-8 开发工具:MyEclipse 参考博客:http://blog.csdn.net/gaohuanjie/article/details/43735891
代码工具类,可以用java代码区分文本文档的编码,非常实用
利用chardet,cpdetector包获取文件格式,并判断文件类型是否带BOM
读取与创建CSV文件,根据第三方jar包自动解析文件编码方式,相关jar包与使用说明
做项目时总结的,java程序获取文件编码方式的两种最常用的方式(1.cpdetector第三方jar包,包含源码elipse项目;2.EncodingDetect.java工具类)。
Java字符编码及获取文件编码
这是一个获取文本的工具类,支持utf8,gbk等等格式的编码。对应位置编码格式的文件使用该工具类便可以获取文件工具类
EncodingDetect.java,java自动获取文件的编码,智能识别文件编码,支持本地file及指定url的编码识别,支持多达40余种编码的识别,包括最常见的UTF-8,GBK,GB2312,BIG5,UNICODE,ISO8859_1,ASCII等,FileUtil....
java 取文件的编码格式 例如UTF-8,GBK,UTF-16,GB2312等等 java 取文件的编码格式 例如UTF-8,GBK,UTF-16,GB2312等等 java 取文件的编码格式 例如UTF-8,GBK,UTF-16,GB2312等等
Java cpdetector获取文件编码格式所需Jar包, 请参照博客进行配置 https://blog.csdn.net/xll_csdn/article/details/109079207
一个判断文件为utf-8的java类,自己用有限状态机实现的,很好用的。
JAVA自动获取文件的编码工具类,使用方法:EncodingDetect.getJavaEncode(String,filePath)