现在的位置: 首页 > 综合 > 正文

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

2011年09月14日 ⁄ 综合 ⁄ 共 2328字 ⁄ 字号 评论关闭

一)需求

很多情况下我们需要知道字节流的编码,比如

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

抱歉!评论已关闭.