字节流编码获取原来这么复杂,但也很简单

一)需求
很多情况下我们需要知道字节流的编码,比如
1) 使用编辑器打开文本文件的时候,编辑器需要识别文本文件的各种编码
2) 上传文件后,分析上传文件字节流需要知道它的编码
3) 读取某个web页面的源代码,并要输出时,需要知道正确的编码才能输出正确的内容

二)探讨
最初和同事讨论如何获取文件/流/字节是否是utf8编码时,发现c#并没有直接的函数,但在SDK中发现UTF8的开头三个字节是“0xEF 0xBB 0xBF”(称为BOM--Byte Order Mark),Unicode文件的开头两个字节是“0xFF 0xFE”,UTF16SmallEndian文件的开头两个字节是“0xFE 0xFF”,于是写了一个简单的函数去解决,由于没有时间做足够的测试,总觉得会有问题.......

/// <summary>
  
/// 解析 byte 数组是什么样的编码
  
/// </summary>
  
/// <param name="enc">要传回的编码类型</param>
  
/// <param name="buff">要解析的byte数组</param>
  
/// <remarks>
  
/// 以下示例演示了如何使用 <see cref="GetEncoding"/>方法
  
/// <code>
  
///  if(Request.Files.Count!=0)
  
///  {    
  
///   //获取上传的文件
  
///   HttpPostedFile pf   = Request.Files[0];
  
///   int fileLength  = (int)pf.InputStream.Length;
  
///   //存储上传文件的字节数组
  
///   byte[] buff   = new byte[fileLength];     
  
///   pf.InputStream.Read(buff,0,fileLength); 
  
///   pf.InputStream.Close();
  
///   Encoding enc = null;
  
///   GetEncoding(out enc,buff);     
  
///   Response.Write("编码:"+enc.EncodingName);
  
///   Response.Write("<br />");
  
///   Response.Write("内容:"+enc.GetString(buff));
  
///  }
  
/// </code>
  
/// </remarks>

  void GetEncoding(out Encoding enc,byte[] buff)
  
{
   
bool flag   = false;
   
//用于测试的编码
   byte[] testencbuff = new byte[0];   
   
int fileLength  = buff.Length;
   
//判断上传的文件的编码是否是Unicode
   enc     = Encoding.Unicode;
   testencbuff   
= enc.GetPreamble();    
   
if(fileLength>testencbuff.Length && testencbuff[0== buff[0&& testencbuff[1]==buff[1])
   
{
    flag 
= true;     
   }

   
//判断上传的文件的编码是否是UTF8
   if(!flag)
   
{
    enc     
= Encoding.UTF8;
    testencbuff   
= enc.GetPreamble();
    
if(fileLength>testencbuff.Length && testencbuff[0== buff[0&& testencbuff[1]==buff[1&& testencbuff[2]==buff[2])
    
{
     flag 
= true
    }

   }

   
//判断上传的文件的编码是否是BigEndianUnicode
   if(!flag)
   
{
    enc     
= Encoding.BigEndianUnicode;
    testencbuff   
= enc.GetPreamble();
    
if(fileLength>testencbuff.Length && testencbuff[0== buff[0&& testencbuff[1]==buff[1])
    
{
     flag 
= true
    }

   }
 
   
if(!flag)
   
{
    enc     
= Encoding.Default;
   }

  }


问题出现了,第二天同事告诉我,不是所有的UTF8编码的文件都有BOM信息,那如何解决呢?他先找到了答案 字节流编码获取原来这么复杂 (我也在google和baidu上搜索过,发现C#并没有很好的解决方案)
以下是两篇相关解决问题的文章(java)
http://dev.csdn.net/Develop/article/10/10961.shtm
http://dev.csdn.net/Develop/article/10/10962.shtm

java代码很容易移植到.NET上,那我就来为大家铺条路...
代码有2400多行,请在这里下载代码:下载代码


在移植代码的过程中感谢以下朋友的参与:
playyuer

posted on 2005-02-24 09:19 Lion 阅读(9219) 评论(14) 编辑 收藏

评论

#1楼  回复 引用 查看   

原来这么复杂,先收藏了以后用得着
2005-02-24 10:37 | myrat      

#2楼  回复 引用   

下载不到,给我发一份吧,谢谢
fangjing3@msn.com
2005-02-24 16:13 | fangjing

#3楼  回复 引用   

现在可以下了
2005-03-11 09:22 | lion

#4楼  回复 引用   

出售蓝奇高级验证码识别引擎,可准确识别新浪动网淘宝CSDN等多种复杂验证码。

输出为一个标准DLL,可供VB,VC,Delphi,C#.NET,VB.NET,模拟精灵,按键精灵等多平台调用,调用方法简单,几行代码即可完成。独具特色的边缘检测字符分离、旋转倾斜纠正和通用字符匹配算法(无论字体和大小), 使得该引擎对于像新浪、动网、淘宝、CSDN等多种验证码均有不错的识别率,是一款效果较为理想的验证码识别引擎。附详细的调用实例和代码注释等相关技术文档。

官方网站 - http://***/yzm_advocr
识别效果怎么样一试就知道 - DEMO下载 http://***/yzm_advocr/advocr.rar

#5楼  回复 引用 查看   

还是下不了哦,老大
2008-05-19 16:34 | 代码乱了      

#6楼  回复 引用   

下载不了
2008-07-03 12:00 | on[未注册用户]

#7楼  回复 引用   

前辈,给我也发一份啊,最近在研究这个哈
2008-10-29 13:25 | 夏田[未注册用户]

#8楼  回复 引用   

确实没办法下载呀,老大有空给我一份呀
邮箱:exc.eption@163.com
正需要呢
2009-05-06 12:24 | miracle_wh[未注册用户]

#9楼  回复 引用   

确实没办法下载呀,老大有空给我一份呀
邮箱:yuanhao2000@gmail.com
正需要呢,万分感谢
2009-05-20 17:16 | bluecloudy[未注册用户]

#10楼  回复 引用 查看   

大哥,我这里也需要呢!也给我一份吧!
419694858@163.com
先谢谢了!
2010-05-28 23:30 | kcc      

导航

<2005年2月>
303112345
6789101112
13141516171819
20212223242526
272812345
6789101112

公告

If you have a dream, do everything for it! If you happy, more happy for you are the happy owner!
If you want happyness, happy in learning, happy in working, and happy in life!
Feel better? Smile ! Believe that everything will be better and better!

昵称:Lion
园龄:7年7个月
粉丝:16
关注:0

搜索

 
 

常用链接

随笔分类

随笔档案

文章分类

文章档案

相册

最新评论

阅读排行榜

评论排行榜

推荐排行榜