Java判斷檔案編碼格式

來源:互聯網
上載者:User

1:簡單判斷是UTF-8或不是UTF-8,因為一般除了UTF-8之外就是GBK,所以就設定預設為GBK。

    按照給定的字元集隱藏檔時,在檔案的最開頭的三個位元組中就有可能儲存著編碼資訊,所以,基本的原理就是只要讀出檔案前三個位元組,判定這些位元組的值,就可以得知其編碼的格式。其實,如果項目啟動並執行平台就是中文作業系統,如果這些文字檔在項目內產生,即開發人員可以控制文本的編碼格式,只要判定兩種常見的編碼就可以了:GBK和UTF-8。由於中文Windows預設的編碼是GBK,所以一般只要判定UTF-8編碼格式。    對於UTF-8編碼格式的文字檔,其前3個位元組的值就是-17、-69、-65,所以,判定是否是UTF-8編碼格式的程式碼片段如下:

File file = new File(path);
InputStream in= new java.io.FileInputStream(file);
byte[] b = new byte[3];
in.read(b);
in.close();
if (b[0] == -17 && b[1] == -69 && b[2] == -65)
System.out.println(file.getName() + ":編碼為UTF-8");
else
System.out.println(file.getName() + ":可能是GBK,也可能是其他編碼");

通過這個方法,只要知道檔案頭儲存的編碼資訊,可以類似判斷檔案是否是某一編碼格式的檔案,不再限於是否是utf-8,就不在贅述。注意這個方法的局限:檔案頭必須有檔案儲存體編碼的資訊,對於不規範的檔案或被篡改過的就另當別論,呵呵。

2:更複雜的檔案編碼檢測,可以使用一個開源項目cpdetector,它所在的網址是:http://cpdetector.sourceforge.net/。它的類庫很小,只有500K左右,cpDetector是基於統計學原理的,不保證完全正確,利用該類庫判定文字檔的代碼如下:

讀外部檔案(先利用cpdetector檢測檔案的編碼格式,然後用檢測到的編碼方式去讀檔案)

/**  * 利用第三方開源包cpdetector擷取檔案編碼格式 *  * @param path *            要判斷檔案編碼格式的源檔案的路徑 */public static String getFileEncode(String path) {/* * 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());java.nio.charset.Charset charset = null;File f = new File(path);try {charset = detector.detectCodepage(f.toURI().toURL());} catch (Exception ex) {ex.printStackTrace();}if (charset != null)return charset.name();elsereturn null;}String charsetName = getFileEncode(configFilePath);System.out.println(charsetName);inputStream = new FileInputStream(configFile);BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, charsetName));

讀jar包內部資源檔(先利用cpdetector檢測jar內部的資源檔的編碼格式,然後以檢測到的編碼方式去讀檔案):

/** * 利用第三方開源包cpdetector擷取URL對應的檔案編碼 *  * @param path *            要判斷檔案編碼格式的源檔案的URL */public static String getFileEncode(URL url) {/* * 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());java.nio.charset.Charset charset = null;try {charset = detector.detectCodepage(url);} catch (Exception ex) {ex.printStackTrace();}if (charset != null)return charset.name();elsereturn null;}URL url = CreateStationTreeModel.class.getResource("/resource/" + "設定檔");URLConnection urlConnection = url.openConnection();inputStream=urlConnection.getInputStream();String charsetName = getFileEncode(url);System.out.println(charsetName);BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, charsetName));

3:探測任意輸入的文字資料流的編碼,方法是調用其重載形式:

charset=detector.detectCodepage(待測的文本輸入資料流,測量該流所需的讀入位元組數);

上面的位元組數由程式員指定,位元組數越多,判定越準確,當然時間也花得越長。要注意,位元組數的指定不能超過文字資料流的最大長度。

4:判定檔案編碼的具體應用舉例:    屬性檔案(.properties)是Java程式中的常用文本儲存方式,象STRUTS架構就是利用屬性檔案儲存體程式中的字串資源。它的內容如下所示:    #備註陳述式    屬性名稱=屬性值    讀入屬性檔案的一般方法是:

FileInputStream ios=new FileInputStream(“屬性檔案名稱”);
Properties prop=new Properties();
prop.load(ios);
String value=prop.getProperty(“屬性名稱”);
ios.close();

    利用java.io.Properties的load方法讀入屬性檔案雖然方便,但如果屬性檔案中有中文,在讀入之後就會發現出現亂碼現象。發生這個原因是load方法使用位元組流讀入文本,在讀入後需要將位元組流編碼成為字串,而它使用的編碼是“iso-8859-1”,這個字元集是ASCII碼字元集,不支援中文編碼,    方法一:使用顯式的轉碼:

String value=prop.getProperty(“屬性名稱”);
String encValue=new String(value.getBytes(“iso-8859-1″),”屬性檔案的實際編碼”);

    方法二:象這種屬性檔案是項目內部的,我們可以控制屬性檔案的編碼格式,比如約定採用Windows內定的GBK,就直接利用”gbk”來轉碼,     如果約定採用UTF-8,就使用”UTF-8″直接轉碼。    方法三:如果想靈活一些,做到自動探測編碼,就可利用上面介紹的方法測定屬性檔案的編碼,從而方便開發人員的工作    補充:可以用下面代碼獲得Java支援編碼集合:    Charset.availableCharsets().keySet();    可以用下面的代碼獲得系統預設編碼:    Charset.defaultCharset();



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.