Java自動獲取文件和文件流編碼

在讀取文件時,如果不清楚文件編碼或者在不同的編碼環境拷貝文件,這時中文數據很可能會出現亂碼,參考了博客: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是探測器,它把探測任務交給具體的探測實現類的實例完成。
		 * cpDetector內置了一些常用的探測實現類,這些探測實現類的實例可以通過add方法 加進來,如ParsingDetector、
		 * JChardetFacade、ASCIIDetector、UnicodeDetector。
		 * detector按照“誰最先返回非空的探測結果,就以該結果爲準”的原則返回探測到的
		 * 字符集編碼。使用需要用到三個第三方JAR包:antlr.jar、chardet.jar和cpdetector.jar
		 * cpDetector是基於統計學原理的,不保證完全正確。
		 */
		CodepageDetectorProxy detector = CodepageDetectorProxy.getInstance();
		
		/*
		 * ParsingDetector可用於檢查HTML、XML等文件或字符流的編碼,構造方法中的參數用於
		 * 指示是否顯示探測過程的詳細信息,爲false不顯示。
		 */
		detector.add(new ParsingDetector(false));
		/*
		 * JChardetFacade封裝了由Mozilla組織提供的JChardet,它可以完成大多數文件的編碼
		 * 測定。所以,一般有了這個探測器就可滿足大多數項目的要求,如果你還不放心,可以
		 * 再多加幾個探測器,比如下面的ASCIIDetector、UnicodeDetector等。
		 */
		detector.add(JChardetFacade.getInstance());// 用到antlr.jar、chardet.jar
		// ASCIIDetector用於ASCII編碼測定
		detector.add(ASCIIDetector.getInstance());
		// UnicodeDetector用於Unicode家族編碼的測定
		detector.add(UnicodeDetector.getInstance());
		
		return detector;
	}
	
	/**
	 * 根據"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字節來判斷文件流的編碼,讀得越多越精確,但是速度慢
				break;
			default:
				charset = Charset.defaultCharset();
				break;
			}
			
		} catch (IOException e) {
			//這裏獲取編碼失敗,使用系統默認的編碼
			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));
	}
	
}

測試結果如下:

文件編碼: GB2312
文件流編碼: GB2312

尤其要注意在獲取文件流編碼時,重載方法detector.detectCodepage(new BufferedInputStream(new FileInputStream(file)),128);的第一個參數必須是包裝的高級流,如果是FileInputStream會包參數異常錯誤.

發佈了30 篇原創文章 · 獲贊 15 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章