字节流编码获取原来这么复杂,但也很简单
来源:互联网 发布:网络中国姓名测试打分 编辑:程序博客网 时间:2024/05/01 02:52
一)需求
很多情况下我们需要知道字节流的编码,比如
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;
}
}
/// 解析 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
- 字节流编码获取原来这么复杂,但也很简单
- 字节流编码获取原来这么复杂,但也很简单
- 字节流编码获取原来这么复杂
- 字节流编码获取原来这么复杂
- 字节流编码获取原来这么复杂
- 优秀编码原来也可以这么容易--编码四原则
- 原来HQL也很简单
- 原来冰箱也这么麻烦
- 原来这么简单(2)
- 原来这么简单。。
- ubuntu下安装mesa原来也这么简单...,不知道clutter怎么样。
- java连连看源码分享(原来连连看这么简单,你也可以写)
- 实体类的枚举属性--原来支持枚举类型这么简单,没有EF5.0也可以
- Linux原来也就这么回事
- 原来这么简单(1)
- 原来这么简单(3)
- 爱,原来就这么简单
- 汉化软件,原来这么简单!
- Linux 指令篇:终端机管理--reset
- 图片渐变轮换效果
- 字节流编码获取原来这么复杂
- Linux 指令篇:编码压缩打包--compress
- 这2个星期在完1个游戏
- 字节流编码获取原来这么复杂,但也很简单
- Linux 指令篇:编码压缩打包--uudecode
- Linux 指令篇:编码压缩打包--uuencode
- mysql 字段类型说明
- Linux 指令篇:文件打印--lpd
- 动态创建二维数组及delete
- Linux 指令篇:文件打印--lpq
- 字符串与数字之间的互相转换
- Linux 指令篇:文件打印--lpr