在讀取文件時,如果不清楚文件編碼或者在不同的編碼環(huán)境拷貝文件,這時中文數(shù)據(jù)很可能會出現(xiàn)亂碼,參考了博客:http://blog.csdn.net/servermanage/article/details/8595676,有了如下的代碼:
?
/**
* 檢測文件的編碼和文本流的編碼
* 參考: http://blog.csdn.net/servermanage/article/details/8595676
* @author Administrator
*
*/
public class CpdetectorUtils {
//獲取文本編碼
private static final String FILE_ENCODE_TYPE = "file";
//獲取文件流編碼
private static final String IO_ENCODE_TYPE = "io";
/**
* 獲取探測到的文件對象
*
* @param path
* 要判斷文件編碼格式的源文件的路徑
*/
private CodepageDetectorProxy getDetector() {
/*
* detector是探測器粪小,它把探測任務(wù)交給具體的探測實(shí)現(xiàn)類的實(shí)例完成糕再。
* cpDetector內(nèi)置了一些常用的探測實(shí)現(xiàn)類,這些探測實(shí)現(xiàn)類的實(shí)例可以通過add方法 加進(jìn)來殴蹄,如ParsingDetector、
* JChardetFacade袭灯、ASCIIDetector、UnicodeDetector橘茉。
* detector按照“誰最先返回非空的探測結(jié)果姨丈,就以該結(jié)果為準(zhǔn)”的原則返回探測到的
* 字符集編碼蟋恬。使用需要用到三個第三方JAR包:antlr.jar、chardet.jar和cpdetector.jar
* cpDetector是基于統(tǒng)計(jì)學(xué)原理的歼争,不保證完全正確沐绒。
*/
CodepageDetectorProxy detector = CodepageDetectorProxy.getInstance();
/*
* ParsingDetector可用于檢查HTML、XML等文件或字符流的編碼,構(gòu)造方法中的參數(shù)用于
* 指示是否顯示探測過程的詳細(xì)信息扮超,為false不顯示申眼。
*/
detector.add(new ParsingDetector(false));
/*
* JChardetFacade封裝了由Mozilla組織提供的JChardet,它可以完成大多數(shù)文件的編碼
* 測定巷蚪。所以濒翻,一般有了這個探測器就可滿足大多數(shù)項(xiàng)目的要求,如果你還不放心淌喻,可以
* 再多加幾個探測器雀摘,比如下面的ASCIIDetector、UnicodeDetector等涯塔。
*/
detector.add(JChardetFacade.getInstance());// 用到antlr.jar、chardet.jar
// ASCIIDetector用于ASCII編碼測定
detector.add(ASCIIDetector.getInstance());
// UnicodeDetector用于Unicode家族編碼的測定
detector.add(UnicodeDetector.getInstance());
return detector;
}
/**
* 根據(jù)"encodeType"獲取文本編碼或文件流編碼
*/
public String getFileOrIOEncode(String path,String encodeType){
CodepageDetectorProxy detector = getDetector();
File file = new File(path);
Charset charset = null;
try {
switch (encodeType) {
case FILE_ENCODE_TYPE:
charset = detector.detectCodepage(file.toURI().toURL());
break;
case IO_ENCODE_TYPE:
charset = detector.detectCodepage(new BufferedInputStream(new FileInputStream(file)),128);//128表示讀取128字節(jié)來判斷文件流的編碼,讀得越多越精確,但是速度慢
break;
default:
charset = Charset.defaultCharset();
break;
}
} catch (IOException e) {
//這里獲取編碼失敗,使用系統(tǒng)默認(rèn)的編碼
charset = Charset.defaultCharset();
System.out.println(e.getMessage());
}
return charset.name();
}
@Test
public void test(){
String path = "F:/DevelopmentSoftware/2016-04-18至2016-04-24記錄.txt";
System.out.println("文件編碼: " + getFileOrIOEncode(path, FILE_ENCODE_TYPE));
System.out.println("文件流編碼: " + getFileOrIOEncode(path, IO_ENCODE_TYPE));
}
}
?
測試結(jié)果如下:
文件編碼: GB2312
文件流編碼: GB2312
尤其要注意在獲取文件流編碼時,重載方法detector.detectCodepage(new BufferedInputStream(new FileInputStream(file)),128);的第一個參數(shù)必須是包裝的高級流,如果是FileInputStream會包參數(shù)異常錯誤.
?