`
k1121
  • 浏览: 179036 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

UTF8最好不要带BOM

 
阅读更多

UTF-8 不需要 BOM,尽管 Unicode 标准允许在 UTF-8 中使用 BOM。
所以不含 BOM 的 UTF-8 才是标准形式,在 UTF-8 文件中放置 BOM 主要是微软的习惯(顺便提一下:把带有 BOM 的小端序 UTF-16 称作「Unicode」而又不详细说明,这也是微软的习惯)。
BOM(byte order mark)是为 UTF-16 和 UTF-32 准备的,用于标记字节序(byte order)微软在 UTF-8 中使用 BOM 是因为这样可以把 UTF-8 和 ASCII 等编码明确区分开,但这样的文件在 Windows 之外的操作系统里会带来问题。

「UTF-8」和「带 BOM 的 UTF-8」的区别就是有没有 BOM。即文件开头有没有 U+FEFF。
UTF-8 的网页代码不应使用 BOM,否则常常会出错。这是一个小例子: 为什么这个网页代码 <head> 内的信息会被浏览器理解为在 <body> 内?

另附《The Unicode Standard, Version 6.0》之 3.10 D95 UTF-8 encoding scheme 的一段话:
While there is obviously no need for a byte order signature when using UTF-8, there are occasions when processes convert UTF-16 or UTF-32 data containing a byte order mark into UTF-8. When represented in UTF-8, the byte order mark turns into the byte sequence. Its usage at the beginning of a UTF-8 data stream is neither required nor recommended by the Unicode Standard, but its presence does not affect conformance to the UTF-8 encoding scheme. Identification of the byte sequence at the beginning of a data stream can, however, be taken as a near-certain indication that the data stream is using the UTF-8 encoding scheme.
http://www.unicode.org/versions/Unicode6.0.0/ch03.pdf

---------------------------------------------------------
首先,BOM是啥。这个就不解释了,Wikipedia上很详细。http://en.wikipedia.org/wiki/Byte_order_mark。
在网页上使用BOM是个错误。BOM设计出来不是用来支持HTML和XML的。要识别文本编码,HTML有charset属性,XML有encoding属性,没必要拉BOM撑场面。虽然理论上BOM可以用来识别UTF-16编码的HTML页面,但实际工程上很少有人这么干。毕竟UTF-16这种编码连ASCII都双字节,实在不适用于做网页。

其实说BOM是个坏习惯也不尽然。BOM也是Unicode标准的一部分,有它特定的适用范围。通常BOM是用来标示Unicode纯文本字节流的,用来提供一种方便的方法让文本处理程序识别读入的.txt文件是哪个Unicode编码(UTF-8,UTF-16BE,UTF-16LE)。Windows相对对BOM处理比较好,是因为Windows把Unicode识别代码集成进了API里,主要是CreateFile()。打开文本文件时它会自动识别并剔除BOM。Windows用这个有历史原因,因为它最初脱胎于多代码页的环境(ANSI环境)。而引入Unicode时Windows的设计者又希望能在用户不注意的情况下同时兼容Unicode和非Unicode(Multiple byte)文本文件,就只能借助这种小trick了。相比之下,Linux这样的系统在多locale的环境中浸染的时间比较短,再加上社区本身也有足够的动力轻装前进(吐槽:微软对兼容性的要求确实是到了非常偏执的地步,任何一点破坏兼容性的做法都不允许,以至于很多时候是自己绑住自己的双手),所以干脆一步到位进入UTF-8。当然中间其实有一段过渡期,比如从最初全UTF-8的GTK+2.0发布到基本上所有GTK开发者都弃用多locale的GTK+1.2,我印象中至少经历了三到四年。

BOM不受欢迎主要是在UNIX环境下,因为很多UNIX程序不鸟BOM。主要问题出在UNIX那个所有脚本语言通行的首行#!标示,这东西依赖于shell解析,而很多shell出于兼容的考虑不检测BOM,所以加进BOM时shell会把它解释为某个普通字符输入导致破坏#!标示,这就麻烦了。其实很多现代脚本语言,比如Python,其解释器本身都是能处理BOM的,但是shell卡在这里,没办法,只能躺着也中枪。说起来这也不能怪shell,因为BOM本身违反了一个UNIX设计的常见原则,就是文档中存在的数据必须可见。BOM不能作为可见字符被文本编辑器编辑,就这一条很多UNIX开发者就不满意。

顺便说一句,即使脚本语言能处理BOM,随处使用BOM也不是推荐的办法。各个脚本语言对Unicode的处理都有自己的一套,Python的 # -*- coding: utf-8 -*-,Perl的use utf8,都比BOM简单而且可靠。另一个好消息是,即使是必须在Windows和UNIX之间切换的朋友也不会悲催。幸亏在UNIX环境下我们还有VIM这种神器,即使遇到BOM挡道,我们也可以通过 set nobomb; set fileencoding=utf8; w 三条命令解决问题。

最后回头想想,似乎也真就只有Windows坚持用BOM了。

P.S.:本问题是自己的第150个回答。突然发现自己回答得很少很少⋯⋯
P.S. 2:突然想起需要解释一下为什么说VIM去除bomb的操作需要在UNIX下完成。因为VIM在Windows环境下有一个奇怪的bug,总是把UTF-16文件识别成二进制文件,而UNIX(Linux或者Mac都可以)下VIM则无问题。这个问题从VIM 6.8一直跟着我到VIM 7.3。目前尚不清楚这是VIM的bug还是我自己那个.vimrc文件的bug。如有高手解答不胜感激。

---------------------------------------------------------

有bom格式在开头会多出3个字节 EF BB BF ,主要用于识别编码。bom应该是windows特有的,在制作网页时会产生各种意想不到的问题,例如多输出了一个空行,影响PHP的session或者cookies功能(出现 header already sent错误),甚至可能引起页面的乱码(那3个字节影响了浏览器对页面编码的处理),因此总是推荐使用无bom编码。为了处理这个问题我甚至写了一个批量处理的PHP脚本。

---------------------------------------------------------
邸强,软件开发ing
张旭东、Mingyue Zhou、sapjax 赞同
几周前还在为BOM的问题苦恼着。。。
正如@梁海所说,“不含 BOM 的 UTF-8 才是标准形式”,的确是这样,无BOM使用得更多些,所以个人还是推荐一般情况下用无BOM的形式吧,除非有问题的时候,再考虑换有BOM的。Windows系统保存的都是有BOM的,所以你可以看到,用记事本保存一个UTF-8的txt,其实是有BOM的,这一点需要注意。另外不同的文本编辑器对于有无BOM的称呼也略有不同,比如EditPlus,有BOM的称为UTF-8+,无BOM的称为UTF-8,而在Notepad++中,有BOM的被称为标准UTF-8,而无BOM则被称为UTF-8无BOM。

---------------------------------------------------------
武龙飞,c/c++ 程序员,喜欢天文学,数学和心理学。
Weijing Huang、Bill Chan、icky R 赞同
以下文字出自我的博客内容,从另一面解说不一样的bom。
---------------------------------------------------------
字符编码相信是每个程序员的噩梦,只要是有中文的地方,总是会遇到各种编码的问题,并且这种问题还非常难缠,尤其在linux上,因为上面很多软件都是针对英语国家开发的,是不会考虑其他语种编码问题。在遇到编码的无数大坑之后,我决定仔细研究下编码问题,因为这就像一道坎一直横在你面前,每次到这里你都会跌到,每次爬起来之后,你都若无其事,这样的人被称作战士,真正的战士。可惜是个力量战士,做为新时代的智力战士,当然不能在那跌到然后又在这继续跌到。
文件的存储方式:
文件都有自己的存储格式,比如最常见的txt,cpp,h,c,xml ,png, rmvb各种格式,还有自定义格式。这些文件不论是什么格式,都是存储在计算机硬盘里的2进制格存储,对应不同文件格式,有不同的软件解析。这篇文章不谈文件是如何存储的,只谈文件是如何解析的。
文本文件解析:
文本文件对应于人类可以阅读的文本,如何从2进制转换为文本文件呢?起初由于计算机在美国发明,自然大家考虑的是英语如何表示,英语字母总共26个,加上特殊字符,128个字符,7位既一个byte即可表示出来。这个就是大家所熟知的ascill编码。对应关系很简单,一个字符对应一一个byte。
但很快发现,其他非英语国家的文字远远超过ascill码,这时候大家当然想统一一下,不同国家出了自己不同的编码方式,中国的gb2312就是自己做出来的编码方式,这样下去每个国家都有自己的编码方式,来回转换太麻烦了。这时候出现了新的编码方式,unicode编码方式,想将编码统一,所以规定了每个字符对应的unicode码。
1、很多文件都是ascii编码,如果用unicode 太浪费。
2、没有标志位说明该几个字节来解析为一个符号。
这时候拯救世界的utf出现了,utf是unicode的一种实现,只不过更聪明了。utf16是占用两字节,或者四字节,utf32是占用四字节。utf8是很聪明的一种表示方式。
1、对于单字节符号,字节第一位为0,后面7位表示字节编码。
2、对于n字节符号,第一字节的前n位都设为1,第n+1位为0,其余位位编码位置。
对于不同的编码,在文本的最前方有不同的标志,unicode 通常有两位来表示分别是ff fe, 或者feff, fffe表示big-endian 编码feff表示litte-endian编码。utf8是efbbbf来开头的。可以看出来utf-8是自解释的,所以不用带这个标志文件,大多数程序是可以识别的。但有些程序不能识别这个标志,比如php就会直接把这个标志当文本解析,不会忽略。相信很多遇到php输出文本解析乱码或者解析错误的同学都遇到这样的问题。
最后说说如何去掉或者加上bom,如果有vim那最好不过了,去掉命令:
set encoding=utf-8
set nobomb
添加命令:
set encoding=utf-8
set bomb
---------------------------------------------------------
带 BOM 的 UTF-8 就是赤裸裸的流氓!!!!!!!!!

windows总是自做聪明的做一些别人无法理解的事情!!!UTF-8是不需要BOM头的~~~!!

从刚开始学习代码(实在不能称我做的东西为程序)到现在,不晓得被这个BOM头搞了多少次,特别是对于我这种完全自学的人,知道找一个BUG需要多久多久不????

带不带BOM头区别就在于这个BOM头,祥见排名靠前的大神答案。windows特有的奇葩。请使用UTF-8 不带BOM头!!

它产生的BUG包含但不仅限于:
锘 -- 感谢 @飞扬 提供,参考其答案
HTML空白行
div之间莫明的间隔
乱码!
如果你用ssl那么一定会有问题!!!

顺便再鄙视一下 SONY的记忆棒、IPHONE的接口~~

这种吐槽的东西就让它折叠吧
--------------------------------------------------------
带 BOM 的 UTF-8 非常操蛋,经常造成莫名其妙的问题。
---------------------------------------------------------
我都是用的UTF-8 without BOM,带BOM的经常出现乱码
---------------------------------------------------------
notepad++会自动添加为带Bom的utf8比较坑爹
---------------------------------------------------------
建议编程人员能使用 Mac 编程的尽量使用Mac,Window是及其操蛋的操作系统。其次,如果我们要读取三方的文件并以UTF-8格式解析的时候一定要注意去判断这个文件是否有BOM,例如:sql文件的解析执行。
---------------------------------------------------------
网页编程中用不用bom我就不说什么了,因为软件原因无法使用的就更不能用了。

最近在学习用cocos2d-x,纯C++的编码,如果代码中有中文等的非ascii字符出现。发现会出错。代码是在mac 下用xcode 写的,放到windows 下用vs 编译。
最后把所有的源文件转成了带bom的格式后编译通过了,链接失败,这想这个就不是编码的问题了。

通常情况下,一般都 会认为在写C++代码的时候不要用中文,但是很多时候我们程序员也有想自己看着舒服的时候,为神马就不能写中文了?

于是在windows 下写了一个helloworld.cpp 类型的文件,输出内容用中文,然后存为utf-8 带bom格式,再把它copy到mac 下用g++ 编译,发现成功通过并且可正常运行,用xcode打开源文件也正常显示。

所以,这里建议程序要在windows 和 mac 还有linux 上运行的话,源代码最好保存成utf-8 带bom的格式,这样比较通用一些。而用utf-16 无论大端还是小端,g++ 都不认的。或者用utf-8 不带bom格式,然后代码不要出现非ascii 127以后的字符。

关于说utf-8 不带bom 才是标准的,我想应该是带用个人情绪的说法吧。真正的标准应该是bom是可选的,为什么可选?因为有些时候不带bom会出错,就拿历史较久远的windows来讲吧,很多国家的用户都在用windows ,其文件都是用其本地的ansi 编码来做的,比如大陆的GBK和GB2013,港台的big5,这些编码因为针对当地所用的字符制定的,所以呢,其存储文件较小,所以会大量使用,并且也大量存在着,微软不可能不考虑全球几十亿的用户的文件而盲目地修改解码方式,并且微软也是uncode 制定者之一,所以,带用bom的utf-8也是符合国际标准的。

或许是因为程序编写者的个人原因,也许是考虑到效率,很多的程序无法正确区分一个utf-8文件是否有bom,所以导致了各种乱码的出现。

个人不想说哪个是标准,也不想用语言去攻击哪个公司或团体。微软在坚持使用bom上没有错,因为这是在为用户考虑的。也许给我们这些写程序的带来了不便,但是,计算机最广泛的用户不是程序员。

分享到:
评论

相关推荐

    gb2312,utf-8,utf-8-bom等编码格式的互相转换

    以上代码片段展示了如何在C#中实现不同编码格式之间的转换,包括GB2312与UTF-8,以及处理带有BOM的UTF-8文件。了解并熟练掌握这些方法,对处理多语言文本数据至关重要。在实际开发中,我们还需要根据具体需求,结合...

    批量utf文件转utf8-bom

    "批量utf文件转utf8-bom"这个主题指的是将一批以UTF编码的文件转换为带有BOM(Byte Order Mark)的UTF-8编码。BOM是一个特殊的字节序列,用于标识文件的编码类型,对于UTF-8编码,BOM的字节序列为0xEF, 0xBB, 0xBF。...

    Java解决UTF-8的BOM问题

    然而,UTF-8有一个特殊特性,那就是它可以带有Byte Order Mark(BOM),这是一个特殊的字节序列,用于标识数据的编码方式。在某些情况下,BOM可能会引起问题,例如在读取文本文件时,可能会导致额外的乱码字符出现在...

    批量去掉UTF-8文件中BOM标示符

    然而,UTF-8编码有一种特殊的形式,即带有BOM(Byte Order Mark)的UTF-8,也被称为UTF-8 with BOM。BOM是一个特殊的字符序列,用于标识文件的编码方式,但在某些情况下,BOM可能会引起问题,例如在某些编程语言中...

    UTF8BOM转换工具

    UTF8BOM转换工具

    C#写入文件加上bom头,主要适用于utf8文件

    writer.WriteLine("这是带有BOM头的UTF-8文件"); } } ``` 在这个例子中,`fileStream`是用于写入的文件流,`writer`是`StreamWriter`实例,用于写入文本内容。`1024`是缓冲区大小,`true`表示在写入后关闭文件流。...

    UTF-8 批量检测BOM工具/小软件 utf8 BOM批量检测/检查清除

    然后用 GB2UTF81.exe 这个工具批量去掉BOM(源文件格式选 utf8,目标文件也选utf8,去掉 带BOM 的勾,不保留备份,再点 开始处理 即可)。然后把目录复制,覆盖原来的目录文件即可。 注意: 本工具暂时还不支持清除...

    utf-8批量bom添加删除(BomChecker)工具

    1.首先介绍一下本人应用场景,qt...3.此小工具主要针对utf-8编码文件,能够批量添加删除BOM,无识别转化ASIIC功能,添加BOM时,如果文件是utf-8(BOM),则跳过,删除亦然 4.当不选中添加删除时可用于文件数量统计。

    PB字符串转XML文件,解决PB12.5创建UTF-8文件BOM问题(powerbuilder 12.5)

    解决PB创建UTF-8文件带BOM问题; 2.字段串直接生成XML文件。 由于项目需要,需要字符串转为XML文件,直接用Fileopen进行EncodingUTF8编码后,发现文件实际为UTF-8 BOM编码 问度娘发现有相同问题,但解决方式是利用...

    UTF8-无BOM转为UTF16LE

    例如,"phonebook_export_unicode_L.csv"可能是使用UTF16LE编码的电话簿数据,而"phonebook_export_utf8.csv"和"phonebook_export_utf8_noBOM.csv"则是使用UTF8编码的,后者没有BOM。 在实际应用中,例如在跨平台的...

    php utf-8编码去bom小工具

    BOM是UTF-8编码的一个可选特征,它在文件开头放置三个特殊的字节来标识文件的字符编码,但这可能会导致在某些编辑器或浏览器中出现不必要的字符或者乱码问题。因此,开发这个小工具是为了帮助开发者处理这个问题。 ...

    utf-8 去除bom头文件

    2. **手动去除BOM**:你可以使用文本编辑器,如Notepad++或Sublime Text,打开UTF-8带BOM的文件,选择“编码”菜单,然后选择“转换为UTF-8无BOM”或类似选项。这样会保存一个新的文件,而原文件保持不变。 3. **...

    无头BOM的UTF8文件判断

    然而,并非所有UTF-8文件都包含BOM,尤其是纯文本文件往往不带BOM,以避免在处理文件时引入额外的字节。 在IT领域,理解和判断无头BOM的UTF-8文件对于软件开发、数据处理和文本分析等工作至关重要。这涉及到以下几...

    remove utf8 bom

    utf8格式的 php 代码里...这个工具就是专门用来删除utf8文件里的bom的。 把文件或者目录拖到工具的主窗口上,他就能自动遍历所有文件,找出带bom的文件。 然后手动判断排除不需要修改的文件,就可以一键 修复BOM 了。

    UTF-8去BOM头工具

    然而,UTF-8编码有一个特性,就是对于某些文件,尤其是文本文件,可能会带有“BOM”(Byte Order Mark),也称为字节顺序标记。 BOM头是UTF-8编码的一个可选部分,用于标识文件的编码方式。它的字节序列是`EF BB BF...

    UTF-8文件去除BOM头小工具

    去除bom头小工具,工具使用方法: 选择要遍历的文件夹,输入...勾选ANSI转为UTF-8,则会将相应格式但编码为GB2312,GBK,GB18030的文件转为无BOM的UTF-8文件 请确保文件可写!使用前请做好备份,作者不承担任何法律责任

    UTF-8文件批量去除BOM标记

    2. 指定需要处理的文件夹路径,该文件夹下所有UTF-8编码且带有BOM的文件都将被处理。 3. 确认设置,如是否创建备份,以免误操作导致原始文件丢失。 4. 开始处理,工具会自动读取文件,移除BOM,并保存为新的文件,原...

    git 修改上传文件编码为utf-8-bom

    当上传文件存在中文时,修改上传文件编码为utf-8-bom

    字符编码转换类,支持 ANSI、Unicode、Unicode big endian、UTF-8、UTF-8+Bom互相转换

    UTF-8的特殊之处在于它包含一个字节顺序标记(BOM),即UTF-8+BOM,但大多数情况下,UTF-8无BOM更常见。 在PHP中,进行字符编码转换可以使用内置函数,如`mb_convert_encoding()`,这个函数可以将字符串从一种编码...

Global site tag (gtag.js) - Google Analytics