获取文件字符集(或文件编码) De 工具类

  1. 云栖社区>
  2. 博客>
  3. 正文

获取文件字符集(或文件编码) De 工具类

sp42 2016-02-04 12:35:00 浏览481
展开阅读全文

http://yongboy.iteye.com/blog/266501

依赖一个 Mozilla 开源的 JAR 包。基于统计来进行字符集探查的,所以并不是百分百准确,并且需要字符串样本足够长。

package org.mozilla.intl.chardet;  
  
import java.io.BufferedInputStream;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.IOException;  
  
/** 
 * 借助JCharDet获取文件字符集 
 * @author icer 
 * PS: 
 * JCharDet 是mozilla自动字符集探测算法代码的java移植,其官方主页为: 
 *      http://jchardet.sourceforge.net/ 
 * @date    2008/11/13  
 */  
public class FileCharsetDetector {  
  
    private boolean found = false;  
  
    /** 
     * 如果完全匹配某个字符集检测算法, 则该属性保存该字符集的名称. 否则(如二进制文件)其值就为默认值 null, 这时应当查询属性  
     */  
    private String encoding = null;  
  
    public static void main(String[] argv) throws Exception {  
        if (argv.length != 1 && argv.length != 2) {  
  
            System.out  
                    .println("Usage: FileCharsetDetector <path> [<languageHint>]");  
  
            System.out.println("");  
            System.out.println("Where <path> is d:/demo.txt");  
            System.out.println("For optional <languageHint>. Use following...");  
            System.out.println("        1 => Japanese");  
            System.out.println("        2 => Chinese");  
            System.out.println("        3 => Simplified Chinese");  
            System.out.println("        4 => Traditional Chinese");  
            System.out.println("        5 => Korean");  
            System.out.println("        6 => Dont know (default)");  
  
            return;  
        } else {  
            String encoding = null;  
            if (argv.length == 2) {  
                encoding = new FileCharsetDetector().guestFileEncoding(argv[0],  
                        Integer.valueOf(argv[1]));  
            } else {  
                encoding = new FileCharsetDetector().guestFileEncoding(argv[0]);  
            }  
            System.out.println("文件编码:" + encoding);  
        }  
    }  
  
    /** 
     * 传入一个文件(File)对象,检查文件编码 
     *  
     * @param file 
     *            File对象实例 
     * @return 文件编码,若无,则返回null 
     * @throws FileNotFoundException 
     * @throws IOException 
     */  
    public String guestFileEncoding(File file) throws FileNotFoundException,  
            IOException {  
        return geestFileEncoding(file, new nsDetector());  
    }  
  
    /** 
     * 获取文件的编码 
     *  
     * @param file 
     *            File对象实例 
     * @param languageHint 
     *            语言提示区域代码 eg:1 : Japanese; 2 : Chinese; 3 : Simplified Chinese; 
     *            4 : Traditional Chinese; 5 : Korean; 6 : Dont know (default) 
     * @return 文件编码,eg:UTF-8,GBK,GB2312形式,若无,则返回null 
     * @throws FileNotFoundException 
     * @throws IOException 
     */  
    public String guestFileEncoding(File file, int languageHint)  
            throws FileNotFoundException, IOException {  
        return geestFileEncoding(file, new nsDetector(languageHint));  
    }  
  
    /** 
     * 获取文件的编码 
     *  
     * @param path 
     *            文件路径 
     * @return 文件编码,eg:UTF-8,GBK,GB2312形式,若无,则返回null 
     * @throws FileNotFoundException 
     * @throws IOException 
     */  
    public String guestFileEncoding(String path) throws FileNotFoundException,  
            IOException {  
        return guestFileEncoding(new File(path));  
    }  
  
    /** 
     * 获取文件的编码 
     *  
     * @param path 
     *            文件路径 
     * @param languageHint 
     *            语言提示区域代码 eg:1 : Japanese; 2 : Chinese; 3 : Simplified Chinese; 
     *            4 : Traditional Chinese; 5 : Korean; 6 : Dont know (default) 
     * @return 
     * @throws FileNotFoundException 
     * @throws IOException 
     */  
    public String guestFileEncoding(String path, int languageHint)  
            throws FileNotFoundException, IOException {  
        return guestFileEncoding(new File(path), languageHint);  
    }  
  
    /** 
     * 获取文件的编码 
     *  
     * @param file 
     * @param det 
     * @return 
     * @throws FileNotFoundException 
     * @throws IOException 
     */  
    private String geestFileEncoding(File file, nsDetector det)  
            throws FileNotFoundException, IOException {  
        // Set an observer...  
        // The Notify() will be called when a matching charset is found.  
        det.Init(new nsICharsetDetectionObserver() {  
            public void Notify(String charset) {  
                found = true;  
                encoding = charset;  
            }  
        });  
  
        BufferedInputStream imp = new BufferedInputStream(new FileInputStream(  
                file));  
  
        byte[] buf = new byte[1024];  
        int len;  
        boolean done = false;  
        boolean isAscii = true;  
  
        while ((len = imp.read(buf, 0, buf.length)) != -1) {  
            // Check if the stream is only ascii.  
            if (isAscii)  
                isAscii = det.isAscii(buf, len);  
  
            // DoIt if non-ascii and not done yet.  
            if (!isAscii && !done)  
                done = det.DoIt(buf, len, false);  
        }  
        det.DataEnd();  
  
        if (isAscii) {  
            encoding = "ASCII";  
            found = true;  
        }  
  
        if (!found) {  
            String prob[] = det.getProbableCharsets();  
            if (prob.length > 0) {  
                // 在没有发现情况下,则取第一个可能的编码  
                encoding = prob[0];  
            } else {  
                return null;  
            }  
        }  
        return encoding;  
    }  
} 

另外参见:encodechecker v0.5 文件编码自动检测及编码转换 GitHub

目前支持如下编码格式
GBK
US-ASCII
ISO-8859-1
utf-8_withoutBom
utf-8_withBom
UTF-16BE_withBom
UTF-16BE_withoutBom
UTF-16LE_withBom
UTF-16LE_withoutBom
UTF-32BE_withBom
UTF-32BE_withoutBom
UTF-32LE_withBom
UTF-32LE_withoutBom

JAVA Unicode 编码和汉字的相互转换  

import java.util.regex.Matcher;  
import java.util.regex.Pattern;

/**
 * 时间:2009-8-25
 *
 * 作者:【轰隆隆】 */
public class T10_BianMa {

    /**
     * java unicode 的相互转换
     */
    public T10_BianMa() {
    }

    public static void main(String[] args){
       
       System.out.println(UnicodeToString("\速\度\中\国"));
       
       String chinese = "中华人民共和国"; 
       for(int i = 0;i<chinese.length();i++){
           System.out.print("\\u" + Integer.toHexString(chinese.charAt(i)));
           //System.out.print(chinese.getBytes("Unicode")[i]);
          
       }
       System.out.println();
      
           
       String str = "\中\华\人\民\共\和\国";    
         
       for(int j = 0;j<str.length();j++) {
           System.out.println(str.charAt(j));
       }
    }

    public static String UnicodeToString(String str) {
        Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");   
        Matcher matcher = pattern.matcher(str);
        char ch;
        while (matcher.find()) {
            ch = (char) Integer.parseInt(matcher.group(2), 16);
            str = str.replace(matcher.group(1), ch + "");   
        }
        return str;
    }

}
将JDK的bin目录加入系统变量path。在盘下建立一个test目录,在test目录里建立一个zh.txt文件,

文件内容为:“熔岩”,打开“命令行提示符”,并进入C:\test目录下。下面就可以按照说明一步一步来操作,注意观察其中编码的变化。

A:将zh.txt转换为Unicode编码,输出文件到u.txt
native2ascii zh.txt u.txt
打开u.txt,内容为“\熔\岩”。
B:将zh.txt转换为Unicode编码,输出到控制台 --Unicode输出文件
C:\test>native2ascii zh.txt       
\熔\岩
可以看到,控制台输出了“\熔\岩”。
C:将zh.txt转换为ISO8859-1编码,输出文件到i.txt
native2ascii -encoding ISO8859-1 zh.txt i.txt
打开i.txt文件,内容为“\?\?\?\?”。
D:将u.txt转换为本地编码,输出到文件u_nv.txt  --输出文件
native2ascii -reverse u.txt u_nv.txt
打开u_nv.txt文件,内容为“熔岩”。
E:将u.txt转换为本地编码,输出到控制台
C:\test>native2ascii -reverse u.txt
熔岩
可以看到,控制台输出了“熔岩”。
F:将i.txt转换为本地编码,输出到i_nv.txt  
native2ascii -reverse i.txt i_nv.txt
打开i_nv.txt文件,内容为“\?\?\?\?”。发现转码前后完全一样的。也就是说,等于没有转,或者说思想糊涂,对命名没有理解。。

G:将i.txt转换为GBK编码,输出到i_gbk.txt
native2ascii -reverse -encoding GBK i.txt i_gbk.txt
打开i_gbk.txt文件,内容为“\?\?\?\?”。发现转码前后完全一样的。也就是说,等于没有转,或者说思想糊涂,对命名没有理解。

H:将u_nv.txt转码到本地编码GBK,输出到控制台
C:\test>native2ascii -reverse -encoding ISO8859-1 i.txt         
熔岩
从这个结果看,目标达到到了,编码i.txt为ISO8859-1,转为本地编码后内容为“熔岩”。
从这里应该意识到,native2ascii -reverse命令中-encoding指定的编码为源文件的编码格式。
而在native2ascii 命令中-encoding指定的编码为(生成的)目标文件的编码格式。这一点非常的重要!切记!!

继续探索,新建文件12a.txt,内容“12axyz”。看看纯字母数字的编码又如何。

I:将纯字母数字的文本文件12a.txt转换为Unicode编码
native2ascii 12a.txt 12a_nv.txt
打开12a_nv.txt文件,内容为“12axyz”。
继续测试,转为ISO8859-1编码看看
C:\test>native2ascii -encoding ISO8859-1 12a.txt
12axyz
结果还是没有转码。


网友评论

登录后评论
0/500
评论
sp42
+ 关注