Java 和 .NET 自动字符编码识别程序库

 
什么是jchardet?

jchardet是mozilla自动字符集探测算法代码的java移植,其源代码可以从 sourceforge 下载。这个算法的最初作者是frank Tang,C++源代码在 http://www.infomall.cn/cgi-bin/mallgate/20040514/http://lxr.mozilla.org/mozilla/source/intl/chardet/ 可以下载。
编译及应用

  将下载后的chardet.zip解压缩后,到~/mozilla/intl/chardet/java/目录下,运行ant即可在dist/lib目录下生成chardet.jar,将这个jar包加入CLASSPATH.然后
运行:java org.mozilla.intl.chardet.HtmlCharsetDetector http://hedong.3322.org
结果:CHARSET = GB18030
运行:java org.mozilla.intl.chardet.HtmlCharsetDetector http://www.wesnapcity.com/
结果:CHARSET = ASCII
运行:java org.mozilla.intl.chardet.HtmlCharsetDetector http://www.wesnapcity.com/blog/
结果:CHARSET = UTF-8

编程使用

  下面就jchardet.jar中的HtmlCharsetDetector.java,对调用jchardet过程予以说明:

public   class  HtmlCharsetDetector  {

    
public static boolean found = false ;

    
public static void main(String argv[]) throws Exception {

    
if (argv.length != 1 && argv.length != 2{

      System.out.println(
            
"Usage: HtmlCharsetDetector <url> [<languageHint>]");

      System.out.println(
"");
      System.out.println(
"Where <url> is http://...");
      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 ;
    }
 

    
/**
    * 初始化nsDetector()
    *lang为一个整数,用以提示语言线索,可以提供的语言线索有以下几个: 
    * 
    Japanese 
    Chinese 
    Simplified Chinese 
    Traditional Chinese 
    Korean 
    Dont know (默认) 

    
*/

    
int lang = (argv.length == 2)? Integer.parseInt(argv[1]) 
                     : nsPSMDetector.ALL ;
    nsDetector det 
= new nsDetector(lang) ;

    
// 设置一个Oberver
    
// 实现nsICharsetDetectionObserver接口,这个接口只有一个Notify()方法.当jchardet引擎自己认为已经识别出字符串的字符集后(不论识别的对错),都会调用这个Notify方法。
    det.Init(new nsICharsetDetectionObserver() {
        
public void Notify(String charset) {
            HtmlCharsetDetector.found 
= true ;
            System.out.println(
"CHARSET = " + charset);
        }

        }
);

    URL url 
= new URL(argv[0]);
    BufferedInputStream imp 
= new BufferedInputStream(url.openStream());
    
    
byte[] buf = new byte[1024] ;
    
int len;
    
boolean done = false ;//是否已经确定某种字符集
    boolean isAscii = true ;//假定当前的串是ASCII编码
       
    
while( (len=imp.read(buf,0,buf.length)) != -1{
        
// 检查是不是全是ascii字符,当有一个字符不是ASC编码时,则所有的数据即不是ASCII编码了。
        if (isAscii)
            isAscii 
= det.isAscii(buf,len);

        
// 如果不是ascii字符,则调用DoIt方法.
        if (!isAscii && !done)
             done 
= det.DoIt(buf,len, false);//如果不是ASCII,又还没确定编码集,则继续检测。
    }

    det.DataEnd();
//最后要调用此方法,此时,Notify被调用。

    
if (isAscii) {
       System.out.println(
"CHARSET = ASCII");
       found 
= true ;
    }


    
if (!found) {//如果没找到,则找到最可能的那些字符集
       String prob[] = det.getProbableCharsets() ;
       
for(int i=0; i<prob.length; i++{
        System.out.println(
"Probable Charset = " + prob[i]);
       }

    }

    }

}


jchardet主要解决什么样的问题?

  Java字符串(及字符)类以Unicode编码保存数据。当处理来自外部的国际性文本时,我们需要提供关于这些文本的编码,以便准确地将它们转换为Unicode。这意味着你必须知道你的java代码要处理的所有文件的编码。许多基于Internet的Java应用程序,要处理来自随机数据源的数据,而很多数据的编码不能确切的知道。例如,一个HTML页面中的数据,如果没有元数据标签明确地指定页面的字符集,就很难确实其编码,将其转换为Java Unicode字符串时也会误用而终止。

  

这个算法是如何工作的?


  浏览器处理这个问题的方法,是对数据一个字节一个字节的检查,以力图测试字符集(当你点击菜单View->Auto-select或auto-detect时)。这个算法(最初由Frank Tang开发)检查字节序列,基于每个字节的值,利用逐步消除法(elimination logic)逐步缩小以至最后确定字符集。如果这个方法仍难以确定,就利用另一个方法,根据某种语言的字符的频次统计来确实字符集。

 什么是NChardet

     NChardet是mozilla自动字符编码识别程序库chardet的.NET实现,它移植自jchardet,chardet的java版实现,可实现对给定字符流的编码探测。

 NChardet是如何工作的

     NChardet通过逐个比较输入字符来猜测编码;由于是猜测,所以可能会有不能完全识别的情况;如果输入字符不能确定正确的编码,那么NChardet会给出一组可能的编码值。

 如何使用NChardet

    要使用NChardet来探测编码,需要进行如下步骤。

    1、使用制定的语言线索来构造Detector类的实例对象。
    2、用实现了ICharsetDetectionObserver接口的对象作为参数来调用Detector类的Init
方法。
    3
、传入要探测的字符流进行编码探测。
    4、调用Detector类的DataEnd
方法。
    5、得到结果或可能的结果集。

    语言线索是一个整数,可用的语言线索有如下几个:

         1.    Japanese
         2.   
Chinese 
         3.   
Simplified Chinese 
         4.   
Traditional Chinese 
         5.   
Korean 
         6.    Dont know (默认
)

    ICharsetDetectionObserver接口只有一个Notify方法,当NChardet引擎认为自己已经探测出正确的编码时,它就会调用这个Notify方法,用户程序可以从这个Nodify方法中得到通知(重写ICharsetDetectionObserver接口的Notify实现)。

代码实例:

// 实现ICharsetDetectionObserver接口
     public   class  MyCharsetDetectionObserver :
        NChardet.ICharsetDetectionObserver
    
{
        
public string Charset = null;
        
        
public void Notify(string charset)
        
{
            Charset 
= charset;
        }

    }




        
int  lang  =   2  ; //
    
// 用指定的语参数实例化Detector
        Detector det  =   new  Detector(lang) ;
    
// 初始化
        MyCharsetDetectionObserver cdo  =   new  MyCharsetDetectionObserver();
        det.Init(cdo);

    
// 输入字符流
    Uri url  =   new  Uri(“http: // cn.yahoo.com”);
    HttpWebRequest request  =
        HttpWebRequest)WebRequest.Create(url);
    HttpWebResponse response 
=
        (HttpWebResponse)request.GetResponse();
    Stream stream 
=  response.GetResponseStream();
    
    
byte [] buf  =   new   byte [ 1024 ] ;
    
int  len;
    
bool  done  =   false  ;
    
bool  isAscii  =   true  ;

    
while ( (len = stream.Read(buf, 0 ,buf.Length))  !=   0 {
        
// 探测是否为Ascii编码
        if (isAscii)
            isAscii 
= det.isAscii(buf,len);

        
// 如果不是Ascii编码,并且编码未确定,则继续探测
        if (!isAscii && !done)
                done 
= det.DoIt(buf,len, false);

    }

    stream.Close();
    stream.Dispose();
    
// 调用DatEnd方法,
    
// 如果引擎认为已经探测出了正确的编码,
// 则会在此时调用ICharsetDetectionObserver的Notify方法
    det.DataEnd();

    
if  (isAscii)  {
        Console.WriteLine(
"CHARSET = ASCII");
          found 
= true ;
    }

    
else   if  (cdo.Charset  !=   null )
    
{
        Console.WriteLine(
"CHARSET = {0}",cdo.Charset);
        found 
= true;
    }

    
    
if  ( ! found)  {
        
string[] prob = det.getProbableCharsets() ;
        
for(int i=0; i<prob.Length; i++{
            Console.WriteLine(
"Probable Charset = " + prob[i]);
        }

    }

    Console.ReadLine();

  

获得NChardet

    NChardet Library (.NET 1.1 and .NET 2.0 ,DLL)

    NChardet Source Code (开发环境为SharpDevelop 2.0)

 版权说明

     本程序移植自jchardet,版权说明请参照jchardet,C#代码采用BSD授权。

 相关链接

    mozilla chardet http://www.mozilla.org/projects/intl/chardet.html
    mozilla chardet 下载  http://lxr.mozilla.org/mozilla/source/intl/chardet/
    jchardet http://jchardet.sourceforge.net/
    SharpDevelop http://www.icsharpcode.net/OpenSource/SD/
    字符集编码的自动识别jchardet http://hedong.3322.org/archives/000361.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值