探测文本文件编码的问题

通常的办法,是读取文件的前几个字节,很多文本文件是在头部用几个字节(BOM,Byte Order Mark)来标识文本文件的编码类型,比如:

UNICODE(little endian): FFFE

Unicode(big endian): FEFF

UTF-8:EFBBBF

等等。

直接先测试。写一段程序(源程序在下面),从本地找一个UTF-8编码的文件里读前几个字节,查看16进制的结果,-_-! 读出来的直接是第一个字符,没有所谓的BOM(EFBBBF,把FEFF按UCS到UTF-8的转换可得到)头,换另外一些文件,都找不到文件所谓的BOM头,但用UE打开看16进制编码确实能看到(UTF-8编码的文件显示FFFE),不解!

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(absolute_file_path));
        int p = (bis.read() << 8) + bis.read();
        bis.close();
        System.out.println(Integer.toHexString(p));

各种测试,大半天,发现用notepad++打开文件,菜单中 格式-->以UTF-8格式编码,保存。运行程序,BOM头读出来了,如果在格式中选择以UTF-8 无BOM格式编码,就读不出来BOM头。

但是用UE十六进制编码查看,却又能看到文件头的FFFE两个字节(UE内部的自动转换,所以看到的不是EFBBBF,不要被这个误导)。

这是什么问题?看样子只能解释为UE会根据文件的内容<不光是BOM头>,来判断文件内容是否是UTF-8编码。查看UE的设置里有一项-->自动检测 UTF-8文件,设置为OFF,再用UE十六进制查看,能看到UTF-8的BOM头了,但是如果有非ascii的字符,显示就有问题了!看样子,UE不会仅根据BOM头去判断文件是否是UTF-8类型???


问题:用nodepad++打开一个UTF-8的文本文件,选择以UTF-8 无BOM格式编码,程序就读不出来BOM头了,但是用UE打开十六进制编辑,又能看到了BOM头,为什么?

解释:UE是根据文件内容判断文件编码格式?在以十六进制方式显示文件内容时,会在头部加上BOM头?用notepad打开该文件,选择另存为,也能看到文件是以UTF-8格式编码,难道Notepad++是监测文件内容来判断文件格式?而不是传说中的根据BOM头?

或者另外一种解释:测试的JAVA代码,从stream读字节,会忽略BOM头?但是用notepad++选择以UTF-8格式编码时,会确实能读出来BOM头,所以代码会忽略BOM头这个结论应该不成立


看样子是第一种解释要合理一点了。如果有朋友有更合理的解释,欢迎提出!


 以下内容更新于2013/10/11 19:06

对于txt文件,如果没有BOM头信息,是无从判断文件的编码格式的.幸好还是有其它办法可以统计出来.例如:juniversalchardet  google code的地址为:https://code.google.com/p/juniversalchardet/ 下面是官网的demo代码:

import org.mozilla.universalchardet.UniversalDetector;

public class TestDetector {
  public static void main(String[] args) throws java.io.IOException {
    byte[] buf = new byte[4096];
    String fileName = args[0];
    java.io.FileInputStream fis = new java.io.FileInputStream(fileName);

    // (1)
    UniversalDetector detector = new UniversalDetector(null);

    // (2)
    int nread;
    while ((nread = fis.read(buf)) > 0 && !detector.isDone()) {
      detector.handleData(buf, 0, nread);
    }
    // (3)
    detector.dataEnd();

    // (4)
    String encoding = detector.getDetectedCharset();
    if (encoding != null) {
      System.out.println("Detected encoding = " + encoding);
    } else {
      System.out.println("No encoding detected.");
    }

    // (5)
    detector.reset();
  }
}

经测试,还比较准确!

我的csdn资源空间里有jar包下载,地址:http://download.csdn.net/detail/kittaaron/6384641

也可以到官网下载!


参考:http://baike.baidu.com/view/414935.htm

http://zh.wikipedia.org/wiki/UTF-8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值