Unicode,UTF-8,GB2312编码的识别

来源:互联网 发布:大学生软件培训 编辑:程序博客网 时间:2024/04/30 14:10
 

Unicode,UTF-8,GB2312编码的识别

在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。

这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。

UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。

Unicode:FF FE

Unicode big_endian:EF FF

UTF-8: EF BB BF

GB2312是高位在前,Big_endian

 

所以现在我们来做个测试就可以很清楚地对以上的东东进行验证了。
1.用notepad输入"汉A"这2个字符﹐然后分别保存成ANSI,Unicode,Unicode-big-endian和UTF-8,名字分别取为ansi.txt,unicode.txt,unicode_b.txt,utf8.txt,并且放在c盘根目录下

2.用以下程序进行验证


using System;
using System.Collections;
using System.IO;

public class MyClass
{
 
private static void writefile(string path)
 
{
  FileStream fs 
= null;
  
try{
   fs 
= new FileStream(path,FileMode.Open);
   
byte[] bs = new byte[fs.Length];
   fs.Read(bs,
0,bs.Length);
   WL(BitConverter.ToString(bs));
   SixTTwo(BitConverter.ToString(bs));
  }

  
catch(Exception ex)
  
{
   WL(ex.ToString());
  }
 
  
finally
  
{
   
if(fs!=null)
    fs.Close();
  }

 }

 
 
public static void Main()
 
{
  
string path;
  WL(
"ANSI文件格式的字节流﹕");
  path 
= "c://ansi.txt";
  writefile(path);
  
  WL(
"Unicode文件格式的字节流﹕");
  path 
= "c://unicode.txt";
  writefile(path);
  
  WL(
"Unicode-big-endian文件格式的字节流﹕");
  path 
= "c://unicode_b.txt";
  writefile(path);
  
  WL(
"utf-8文件格式的字节流﹕");
  path 
= "c://utf8.txt";
  writefile(path);
  RL();
 }

 
 
public static void SixTTwo(string sixstr)
 
{
  
string[] tmp = sixstr.Split(new char[]{'-'});
  
foreach(string s in tmp)
  
{
   

Console.Write(Convert.ToString(Convert.ToByte(s,
16),2).PadLeft(8,'0')+ " 

");
  }

  WL(
"");
 }

 
 
private static void WL(string text, params object[] args)
 
{
  Console.WriteLine(text, args); 
 }

 
 
private static void RL()
 
{
  Console.ReadLine(); 
 }

 
 
private static void Break() 
 
{
  System.Diagnostics.Debugger.Break();
 }

}



3.以下是输出格式﹕
ANSI文件格式的字节流﹕
BA-BA-41
10111010 10111010 01000001
Unicode文件格式的字节流﹕
FF-FE-49-6C-41-00
11111111 11111110 01001001 01101100 01000001 00000000
Unicode-big-endian文件格式的字节流﹕
FE-FF-6C-49-00-41
11111110 11111111 01101100 01001001 00000000 01000001
utf-8文件格式的字节流﹕
EF-BB-BF-E6-B1-89-41
11101111 10111011 10111111 11100110 10110001 10001001 01000001

从以上结果可以很容易的看到BABA正是"汉"字的gb2312编码﹐当然我的操作系统是繁体的﹐如果我直接双击打开﹐则可以看到"荦A"﹐这是乱码﹐因为我的系统baba查的是big5﹐而baba的big5码正是"荦"

然而还有其它很多程序﹐像IE呀,它可以使用meta标签来识别文件的编码,xml也是可以通过encoding属性来说明文件的编码的﹐所以这些程序的识别方法和普通的又有些不同罢了。

同样﹐写一个文本文件时﹐先写入这些标记符﹐则也会帮助notepad识别这些文件的编码(当然.net专门提供了一些类别﹐如StreamWriter﹐可以直接存成某种编码的格式)。

至于各种encoding之间的转换﹐我想也不必多说了﹐通过Encoding类的Convert,GetBytes和GetString方法是很容易进行转换的。

原创粉丝点击