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

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
结果还是没有转码。

时间: 2024-09-15 14:26:11

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

各种格式的编码解码工具类分享(hex解码 base64编码)_java

复制代码 代码如下: import java.io.UnsupportedEncodingException;import java.net.URLDecoder;import java.net.URLEncoder; import org.apache.commons.codec.DecoderException;import org.apache.commons.codec.binary.Base64;import org.apache.commons.codec.binary.Hex;im

Java base64编码解码工具类

    前几天无意中看到Java中有Base64编码,不解的我去百科了一下,了解了Base64的基本使用和实现原理,于是在空暇时自己手动写了一个,这个类可以完成对字母数字的编码和解码工作,但是对于中文,还没有仔细研究其编码的实现过程.至于什么是Base64,用它来干什么,请移步到:http://zh.wikipedia.org/zh-cn/Base64  下面贴出这个工具类的源代码,供朋友们参考,本人新手写得不好,请用力拍砖: /************************Base64Uti

Java 中按文件名称分类,按文件大小分类,按照文件类型分类,按照最后修改时间分类的工具类

在此博客中用到了文件操作的工具类,可以连接 Java中实现复制文件到文件,复制文件到文件夹,复制文件夹到文件,删除文件,删除文件夹,移动文件,移动文件夹的工具类 package cn.edu.hactcm.cfcms.utils; import java.io.File;import java.util.HashSet;import java.util.Set; import javax.swing.JOptionPane;/** * 文件分类中用到的所有工具类 * CFMS    :Compu

翻翻git之---实用工具类Lazy(绝对的好东西,走过路过别错过)

转载请注明出处:这里写链接内容 今天还是继续昨天的从Git上找点"有用的","好玩的","推荐的"东西给大家,今天贴的是一个工具类.地址如下https://github.com/ddwhan0123/Lazy 原作者Blog:http://weibo.com/2675061813/profile?topnav=1&wvr=6 他有一些比较常用的,诸如设备状态啊,土司啊,窗口啊,测量啊什么的,还有些我觉得平时回去搜,但是不多的资源,如拼音和

java工具类之实现java获取文件行数_java

工具类代码,取得当前项目中所有java文件总行数,代码行数,注释行数,空白行数 复制代码 代码如下: import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.io.Reader;import

我的Java开发学习之旅------&amp;gt;工具类:Java获取字符串和文件进行MD5值

ps:这几天本人用百度云盘秒传了几部大片到云盘上,几个G的文件瞬秒竟然显示"上传成功"!这真让我目瞪口呆,要是这样的话,那得多快的网速,这绝对是不可能的,也许这仅是个假象.百度了一下才发现所谓的"秒传"是常见的"忽略式"上传方式,就是您上传了一个文件名为111.exe,MD5为一个数,有一个网友以前也上传一个叫222.exe,MD5和您上传的文件MD5码一模一样,所以这个文件上传到服务器上的时间就很短了,这是因为别人上传过这个文件,您上传这个文件

Java获取文件大小,文件夹内文件个数的工具类

package cn.edu.hactcm.cfcms.utils; import java.io.File;import java.io.FileInputStream;import java.text.DecimalFormat;/**  * CFMS    :Computer files management system   * version :1.0 2013-3-2 下午03:33:07 */public class FileInfoUtils {  /**  * 获得文件类型(文

java处理字符集-第二部分-文件字符集

前面有一篇文章提及到乱码的产生:http://blog.csdn.net/xieyuooo/article/details/6919007 那么知道主要原因是编码和解码方式不一样,那么有些时候如果我们知道编码方式,那么解码自然很好搞,例如输出的contentType会告诉浏览器我输出的内容是什么编码格式的,否则浏览器会才用一个当前默认的字符集编码来处理:本文要将一些java如何处理没有带正常协议头部的字符集应当如何来处理. 这里就说的是文件字符集,在了解字符集之前,回到上一篇文章说到默认字符集,

如何在LINUX中修改文件字符集

有些情况下,我们需要修改文件的字符集,以便解决乱码或者其他问题.在linux下,操作系统为我们提供了ICONV这个命令,下面我们来看一下这个命令的具体使用方法. [root@oadata ~]# iconv --help 用法: iconv [选项...] [文件...] 转换给定文件的编码. 输入/输出格式规范: -f, --from-code=名称 原始文本编码 -t, --to-code=名称 输出编码 信息: -l, --list 列举所有已知的字符集 输出控制: -c 从输出中忽略无效