utf-8格式之no bom和+bom

  utf-8 编码的文件可以分为no bom 和 bom两种格式。

  何谓bom?

  "ef bb bf" 这三个字节就叫bom,bom的全称叫做"byte order mard".在utf-8文件中常用bom来表明这个文件是utf-8文件,而bom的本意实在utf16中用来表示高低字节序列的。在字节流之前有 bom表示采用低字节序列(低字节在前面),而utf8不用考虑字节序列,所以其实有无bom都可以。utf-8以字节为编码单元,没有字节序的问题。 utf-16以两个字节为编码单元,在解释一个utf-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的unicode编码是 594e,“乙”的unicode编码是4e59。假如我们收到utf-16字节流“594e”,那么这是 “奎”还是“乙”?

  假如文件保存时,选择了使用 bom,那么就可能会出现 headers already sent 的问题。
  因为 web 服务器软件可能不了解 bom,所以就把 bom 的两个非凡字节当做字符发送给浏览器了。
  这时再调用 session_start() 等函数,就会出现 headers already sent 的问题。
  所以解决此问题最根本的方法就是在保存 utf8 编码文件时,不要使用 bom。

  微软的记事本 word 等只能正确打开含bom的utf8文件,然后ultraedit却恰恰相反,回把bomutf8文件 误认为ascii编码。

  utf-8的bom是 efbbbf,因为ue载入utf-8文件会转成utf16,上述的efbbbf 在utf16中是fffe(unicode-le的bom),

  ultraedit不了解bom又加多一個bom,所以有2个fffe。文件就被它破坏了。


  当应用程序的文件使用 utf8 编码时,在保存文件时,一定要注重 bom 的问题。

  那么如何将utf8 without bom转换成utf8呢?




using (textreader input = new streamreader(
  new filestream(@"c:\test.properties", filemode.open), encoding.utf8)
  )
{
    
using (textwriter output = new streamwriter(
  new filestream(@"c:\test2.lmx", filemode.create), encoding.utf8)
  )
    
{
        
int buffersize = 8096;
        
char[] buffer = new char[i];
        
int len;

        
while ((len = input.read(buffer, 0, i)) > 0)
        
{
            output.write(buffer, 
0, len);
        }


        input.close();
    }

}
posted @ 2011-03-16 11:28  Mamboer  阅读(1770)  评论(0编辑  收藏  举报