没有BOM的utf-8和utf-8有什么不同?哪个更好?
- "更好"是什么意思?更短的"?"更便携"?
- UTF-8可以更好地由内容自动检测,而不是由BOM自动检测。方法很简单:尝试将文件(或字符串)读取为utf-8,如果成功,则假定数据为utf-8。否则,假设它是CP1252(或其他一些8位编码)。任何非UTF-8八位编码几乎肯定包含UTF-8不允许的序列。纯ASCII(7位)被解释为UTF-8,但这样的结果也是正确的。
- 扫描大文件中的UTF-8内容需要时间。BOM使这个过程更快。在实践中,你经常需要同时做这两件事。现在的罪魁祸首是,仍然有很多文本内容不是Unicode,我仍然碰到一些工具,它们说它们使用Unicode(例如UTF-8),但它们的内容是另一种代码页。
- @我真的不认为"更好的"适合这种情况。这取决于环境。如果您确定所有的UTF-8文件都标记了一个BOM,那么检查BOM是"更好"的方法,因为它更快、更可靠。
- UTF-8没有物料清单。当您将U+FEFF代码点放在UTF-8文件的开头时,必须特别注意处理它。这只是微软命名谎言中的一个,就像在没有这种东西的情况下调用编码"unicode"。
- @没有一种方法可以一直工作。元数据可能是错误的——可能是拉丁语1,但实际上是UTF-8,或者相反。数据可能被破坏,或者生成错误,所以仅仅因为它是无效的UTF-8并不意味着它最好解释为"有点破坏的UTF-8"。通常情况下,就是这样。BOM有助于区分"损坏/无效的UTF-8"和"损坏/无效的Latin1"
- 除非你有特殊的需要,否则你通常不想要这个。例如,它可以从一个PHP片段回显到HTML中。现代大型机(和AIX)支持小endian utf-8,即使这不是"本机的"。只要你标准化,你就应该没事。
- "现代大型机(和AIX)是小endian的utf-8感知型"utf-8没有endence!对于一个特定的系统,将四对或四组按正确的"顺序"排列是不会改变字节的!要检测一个UTF-8字节序列,需要注意的是,多字节序列"码位"(不是"普通"的ASCII字节)的第一个字节设置了MS位,并且所有1到3个以上的连续低有效位后面跟着一个复位位。这些集合位的总数比该代码点中的字节少一个字节,它们都将设置msb…
- 没有区别,因为UTF-8没有BOM。utf-8+bom是utf-8+bom,这不是一个标准:使用了我的微软,也许还有其他一些。
- 如果这对其他任何人都有帮助,我注意到(至少对于网站而言)在Windows服务器上的IIS中,总是用BOM将文件保存为UTF-8(当您在"另存为"对话框的"编码"下拉菜单中选择它时,常规记事本会这样做)。但是在Unix服务器上,我总是将文件保存为UTF-8而不带BOM(因为当我的Apache服务器读取我的PHP文件(如果它们有BOM的话)时,我有编码问题)。记事本+有一个伟大的"编码"菜单,帮助从一个转换到另一个。
- 在阅读有关添加BOM的(假定的)实用程序的讨论时,我想知道:由于大多数其他代码页没有或(假定的)需要代码页标识,为什么要使用UTF?为什么唯一必须更改的代码页是UTF?为什么不为Windows-1252、DOS-852或ISO 8859-1提供一个BOM(或等同于检测编码)?这是非常不公平的要求。只有微软想强加的。:
- @箭头"字节顺序"是指当您有两个或多个字节代表一个字符时,您需要知道它们的位置,这样您才能正确地读取它们。windows-1252、iso-8859-1等都是单字节编码,每个字符只有一个字节,所以不需要字节顺序标记来说明以何种方式读取它们。它们并不是用来检测正在使用哪种编码的,而是用来检测编码的,因为在其他情况下根本没有自动的方法来判断。但他们对此并不可靠。多字节编码的bom不是微软的东西,只有utf8+bom是。
- 事实1:utf-8是以网络顺序传输的面向字节的编码,没有"字节顺序",不需要"字节顺序"。事实2:Windows对ucs-2的使用与utf-16非常相似,是一种多字节编码,微软没有为其指定BOM。把你的事实弄对@tesssellangheckler。
- @"把我的事实弄对"箭头?我弄错了什么事实?你的事实与我所说的没有矛盾。
- 你是那个引入"字节顺序"概念的人,而不是我(我最初的评论没有提到这一点)。但是UTF-8不需要字节顺序检测或描述。它由一系列字节组成。因此,不需要使用UTF-8来标记字节顺序。…识别:UTF-8是最可靠的正确检测编码(当使用128以上的Unicode码位时),不需要BOM。…同样:fact-1:utf-8不需要"字节顺序"。事实2:微软使用的是(假设)2字节的编码,没有bom,为什么在其他编码中需要bom?@镶嵌式Eckler
- UTF-8是一个字节流,因此它实际上没有字节顺序,但在本例中,3字节的BOM仍然充当签名。软件应该知道编码是ANSI还是UTF-8。如果将UTF-8内容视为ANSI编码,则结果字符将是错误的,因为序列的字节将被视为单个字符,而这是错误的。另一方面,如果软件将ANSI编码的文件视为UTF-8,则会因序列中断或不完整而出错。
- @阿罗,你在反对我从未说过的话。编码哪个/需要/一个BOM需要它/告诉你字节顺序/。不需要/BOM的编码不需要它来告诉您字节顺序。UTF-8在规范中有一个可选的BOM,可以滥用它来检测UTF-8的使用。这不是"改变标准",这就是它不同于经典代码页的原因。这不是检测UTF-8的字节顺序,我从来没有说过。您在说"添加BOM的(假定的)实用程序"时引入了字节顺序。微软在哪里使用2字节/无物料清单?dotnet使用2字节+bom作为一个例子。
utf-8bom是文本流(ef bb bf)开始时的一个字节序列,它允许读者更可靠地猜测文件是用utf-8编码的。
通常情况下,BOM用于表示编码的结束地址,但是由于结束地址与UTF-8无关,因此BOM是不必要的。
根据Unicode标准,不建议使用UTF-8文件的物料清单:
2.6 Encoding Schemes
... Use of a BOM is neither required nor recommended for UTF-8, but may be
encountered in contexts where UTF-8 data is converted from other
encoding forms that use a BOM or where the BOM is used as a UTF-8
signature. See the"Byte Order Mark" subsection in Section 16.8,
Specials,
for more information.
- 可能不建议这样做,但根据我在希伯来语转换方面的经验,BOM有时对Excel中的UTF-8识别至关重要,可能会使Jibrish和希伯来语之间产生差异。
- 可能不建议这样做,但在尝试输出"&230;&248;&229;"时,它对我的PowerShell脚本产生了奇迹。
- 不管标准不推荐它,它是允许的,而且我非常喜欢用某种东西作为UTF-8签名,而不是假设或猜测的替代方案。符合Unicode的软件应该/必须能够处理它的存在,所以我个人鼓励使用它。
- @马蒂诺还有另一种猜测和假设的替代方法:正确存储编码元数据。UTF-8BOM是一种黑客的尝试,但是因为元数据存储在主数据流中,所以实际上相当于猜测。例如,没有什么能说明我的ISO 8859-1编码的纯文本文件不能以字符"&239;&187;&191;"开头,这与UTF-8 BOM不可区分。指示纯文本文件编码的正确方法是,例如,文件系统属性。
- @BAMES53:是的,在理想的情况下,将文本文件的编码存储为文件系统元数据将是更好的保存方法。但是我们大多数生活在现实世界中的人无法改变我们程序运行的操作系统的文件系统,所以使用Unicode标准的平台独立的BOM签名似乎是最好和最实用的替代IMHO。
- @与Linux和OS X一起使用的文件系统一样,martineau ntfs支持任意文件属性。事实上,OS X使用扩展属性进行文本编码,并且有一种方案,即使在本机不支持这些属性的文件系统(如fat32和inside-zip文件)上,也可以保留这些属性。BOM并不是一个更实用的解决方案,它是一个愚蠢的解决方案(毕竟,它仍然只是猜测),病毒的特性让它积累了大量的惰性。
- @BAMES53:每个操作系统都有不同的方式来访问和解释元数据,而且这是一个只能预期会继续下去的条件,而且在将来可能会变得更糟。从技术上讲,使用UTF-8BOM可能是一种猜测,但事实上,对于文本文件来说,它不太可能是错误的。很明显,我们对"实用"的含义有不同的看法…
- @就在昨天,我偶然发现一个带有UTF-8 BOM的文件,它不是UTF-8(它是CP936)。不幸的是,那些对UTF-8BOM造成的巨大痛苦负责的人在很大程度上忽视了它。
- @barnes53-文件系统属性不会应用于以BOM开头的HTTP请求或响应。(事实上,这种情况正是我提出这个问题的原因。)
- 当在Tomcat服务器中工作并使用带有bom的utf-8法语属性文件时,浏览器不知何故会生成一个询问符号"?"在文件的开头,这会使特定的属性文件在生产环境中无效,并破坏JavaScript代码。到目前为止,我们唯一的解决方法是为法国的javascript文件保存不带bom的utf-8文件。奇怪的行为,肤浅的工作环境。:(
- @will824看起来Web服务器没有发送正确的编码。看看你的配置。
- 我不是这里的最后一个词,但我想你在解释标准时,用的是非正式的意义。对于一个标准机构来说,推荐一些东西,这意味着它们正式地给出了首选用法的规范性指示。不推荐就是不提供意见。""既不是必需的,也不是推荐的",这并不意味着Unicode标准建议您不要对utf-8文件使用utf-8签名——这只是意味着它们不会以一种或另一种方式站在一边。
- 我发现有些编码检测库只能在存在BOM时正确猜测UTF-8。否则,启发式似乎不是100%准确。
- 另外请注意,Windows似乎默认使用一个用于UTF-8的BOM,并且许多Microsoft程序不尝试启发式检测,因此如果缺少BOM,它将无法正确解码文件。
- BOM应该被认为是强制性的,而不推荐是Unicode标准的主要缺点之一,可能也是多年来UTF-8仍然存在问题的主要原因。
- @加勒特威尔逊,我同意你的解释,这仅仅意味着他们没有采取一种或另一种立场。但这也意味着,包括一个解决不了实际问题的BOM,至少是多余的。并带来一些不必要的不良后果。至少这个。
- @关于Excel,这是微软的产品(也不推荐微软)。有些时候,当做一些不被推荐的事情时,就有必要做一些不被推荐的事情。标准中提到有时会遇到BOM的段落是作为对微软使用该BOM的回应而添加的。
- @实际上,在理想的情况下,每个文件都应该有一个预先定义的字节长度的唯一签名,包括文本文件(每个编码一个)。这样就不需要启发式方法了。就像HTTP协议中的内容类型一样。
- @埃里克格兰奇-你的评论让我怀疑你从来没有经历过UTF-8 BOM可能导致的许多问题。通过连接字符串建立输出是非常常见的;如果这些字符串是用BOM编码的,那么现在在输出的中间就有了一个BOM。这只是问题的开始。不需要指定UTF-8中的字节顺序,使用BOM作为编码检测器是有问题的,因为其他原因。
- +rmunn您所描述的问题实际上是很容易解决的,因为BOM是一个没有其他含义的特殊序列,始终拥有一个BOM不会带来任何歧义,因为它可以被安全地检测到。另一方面,没有BOM的存储字符串只能通过元数据和约定知道是UTF-8。这两者都是脆弱的,文件系统在两者上都会发生故障,因为唯一的元数据通常是文件扩展名,它只是松散地暗示了内容编码。有了强制的bom实现,100%的时间都可以安全地进行,没有bom,只有猜测和祈祷…
- @EricGrange的utf-8bom确实有一些严重的问题,尽管这个问题实际上不是由bom本身引起的。也就是说,由于既不是必需的也不是推荐的,所以有大量的代码可以在没有BOM的情况下处理UTF-8,但是会阻塞BOM本身。因此,很可能他们不推荐它是因为这个已知的问题,但问题是由于它没有被推荐,实际上是一个自我喂养周期。
- (原因的另一部分可能是,虽然代码仍在活动开发中,但如果需要,可以更新以使用BOM,但过时的通常不能,这可能会在需要和无法替换的情况下导致问题。)
- 除此之外,理论上它还可能导致其他编码方案中的文件出现误报,这些编码方案不幸地以UTF-8 BOM开头(例如以ABC开头的ISO-8859-1文件),但这种情况不太可能出现在恶意或设计不良的软件之外。我个人认为它可以提高检测UTF-8的效率,尽管老实说我还不太擅长使用Unicode。
- @BAMES53:是的,UTF-8 BOM可能被错误地解释为"真实"字符&239;&187;&191;。但对于UTF-16 BOM(big endian)也是如此,它可能被错误地解释为"真实"字符&254;&255;。为了保持一致,一个人应该在总体上支持BOM,或者在总体上反对它们。考虑到我们绝对不能消除UTF-16中的bom,我们也应该接受UTF-8中的bom。
- @军火师,我们也不需要UTF-16的BOM。规则是不允许utf-16be或utf-16le具有BOM。对于UTF-16,规则是,在缺少bom endianness的情况下,与存储数据的介质相匹配(例如,在小endian机器的内存中使用小endian,在网络连接上使用网络字节顺序),如果没有这样高级别的协议,则使用大endian。这将在Unicode标准的3.10中讨论。
- @Garretwilson我在Unicode标准中看到了"不推荐"的其他例子,其中它清楚地表示"我们建议你不要…",例如,在3.6中看到P8的最后一个要点。对UTF-8BOM的评论可能没有那么清晰,但有些示例似乎更倾向于这种方式。例如,Unicode标准建议"不使用UTF-8 BOM",但它的存在并不影响对UTF-8编码方案的一致性。"我们建议不使用它,但它不会使流不一致。"否则,"but"子句是愚蠢和多余的。
其他优秀的答案已经回答了:
- utf-8和bom-ed utf-8没有官方区别
- 一个bom-ed utf-8字符串将以以下三个字节开始。EF BB BF
- 从文件/流中提取字符串时,必须忽略这些字节(如果存在)。
但是,作为这方面的附加信息,如果字符串是用UTF-8编码的,那么UTF-8的BOM可能是一种很好的"嗅觉"方法…或者它可以是任何其他编码中的合法字符串…
例如,数据[EF BB BF 41 42 43]可以是:
- 合法的ISO-8859-1字符串"????美国广播公司"
- 合法的utf-8字符串"abc"
因此,虽然通过查看第一个字节来识别文件内容的编码很酷,但是您不应该依赖于此,如上面的示例所示
编码应该是已知的,而不是占卜的。
- 对不起,先生,我不太明白你刚才举的例子。如果我有一个字符串[EF BB BF 41 42 43],我如何解释它?使用ISO-8859-1或UTF-8?因为正如你的例子所说,两者都会给出一个合法的字符串:"&239;&187;&191;abc"和"abc"。
- @阿尔科特:你理解正确。字符串[ef bb bf 41 42 43]只是一堆字节。您需要外部信息来选择如何解释它。如果您认为这些字节是使用ISO-8859-1编码的,那么字符串是"&239;&187;&191;abc"。如果您认为这些字节是使用UTF-8编码的,那么它就是"abc"。如果你不知道,那么你必须设法找出答案。物料清单可能是个线索。当解码为UTF-8时缺少无效字符可能是另一个…最后,除非您能够以某种方式记忆/查找编码,否则字节数组就是字节数组。
- @paercebal虽然"&239;&187;&191;"是有效的拉丁语-1,但文本文件不太可能以这种组合开头。UCS2 LE/BE标记&255;&254;和&254;&255;也适用。你也永远不知道。
- @用户确实不太可能,但完全有效。你不能百分之百肯定地说它不是拉丁语1。
- @decize它可能在语言上是无效的:首先&239;(这是正常的),然后是一些引号,中间没有空格(不正常)。¿;表示它是西班牙语,但&239;未在西班牙语中使用。结论:它不是拉丁语-1的确定性远远高于没有它的确定性。
- @当然,这不一定有意义。但是,如果你的系统依赖于猜测,那就是不确定性的来源。一些恶意用户故意提交以这3个字母开头的文本,而您的系统突然假设它正在使用BOM查看UTF-8,将文本视为UTF-8,在那里它应该使用拉丁语-1,并进行一些Unicode注入。只是一个假设的例子,但肯定是可能的。不能根据文本编码的内容、句点来判断文本编码。
- @我说是UTF-8吗?我只说了不该说的。在我猜测之后,我将验证数据,使其符合UTF-8编码规则(可以在读取时完成)。如果没有,并且文本是一路存储的,则返回到另一个8位编码。如果未存储文本,则拒绝输入。它很像PNG中的校验和。
- @用户不,你没有。但我是说,如果你看一个字符串的内容来确定它的编码,有可能你会陷入奇怪的情况。例如,您的系统可能无法正确接受以"&239;&187;&191;"开头的拉丁-1文件。虽然这种情况不太可能发生(我不反对),但这仍然是一种可能性。我更喜欢编写正确的代码,而不是在以下情况下可能中断的代码……
- @在这种情况下,没有正确的代码:-(
- 如果它看起来和闻起来像…UTF-8…可能是UTF-8。为什么让你的生活更难思考复杂的边缘案件?
- "编码应该是已知的,而不是占卜的。"问题的核心和灵魂。+ 1,好先生。换句话说:要么标准化你的内容,然后说,"我们一直在使用这种编码。时期。这样写。这样读,"或者开发一种扩展格式,允许将编码存储为元数据。(后者可能也需要一些"引导标准编码"。比如说"告诉你编码的部分总是ASCII码。")
- 如果文本是一些奇怪的Unicode字符,单代码点需要大于1个字节,那么现在不应该是bom?
- @Royinamir:bom的存在或不存在不会影响在utf-8中使用合法的Unicode字符,不管是否奇怪。请你澄清一下这个问题好吗?
- @当然,这是"A"的字节表示。"A"只有一个UTF-8字节,所以这里不需要BOM。但是这个炭呢?这里有4个字节。这里不应该有BOM吗?我希望我的问题现在清楚了。
- @Royinamir:虽然bom可以"帮助"用户怀疑文件是Unicode的,而不是ISO-8859-1,但你不能百分之百地确定这一点。假设我给你发了一个简单的文本文件,里面有四个字节的中文(?)glyph,告诉你它是utf-8。然后,您可以在不依赖BOM的情况下对其进行解码。另一种情况是,如果我向您发送一个ISO-8859-1文件,其中的第一个字符与BOM的字节非常相同,那么您仍然必须将其解码为ISO-8859-1。不是UTF-8。只有当我发送一个文本文件而不告诉您它的编码时,拥有BOM的三个字节将指导您。或者误导你。
- "编码应该是已知的,而不是占卜的。"告诉使用JSON的Wackos:(ietf.org/rfc/rfc4627.txt
- @Royinamir——在您给出的示例(i.imgur.com/7u1zlrs.png)中,仍然不需要使用UTF-8格式的BOM,因为它的字节顺序是由标准定义的。无论你是在小尾数还是大尾数系统上,字符??(U+20B20)将始终只有一个有效的UTF-8编码,即四字节序列F0 A0 AC A0。这些字节的字节顺序是由UTF-8标准严格定义的,因此在UTF-8中不需要任何字节顺序标记。(使用它作为编码标识符是另一个问题;我特别指出不需要它来标识字节顺序。)
- 在一万亿个文本文件中,我怀疑是否有一个(非恶意的)以utf-8bom开头,而这个bom并不打算是utf-8bom。不管怎样,任何恶意都必须得到处理,不管是bom还是no bom。所以,清理您的输入,如果有一个BOM,也许您可以使用它来稍微加快您的处理速度。我看不出问题所在。
- @deceze:我遇到了实际上没有编码的文本文件。PHP是一个讨厌的野兽,您确实可以有一个输出阶梯,其中不同的路径导致不同的编码被输出,并且在这两个阶梯中都有常量。
- @乔舒亚没有编码就没有文本文件。可能是无法确定的编码,但不是没有编码。
- @减速:编辑文件中的输出字符串需要关闭编辑器,切换会话编码,然后再次打开文件来执行这两个设置。一半的字符串看起来总是像垃圾。
- @乔舒亚说,简短的描述不足以说明那里发生了什么,但这听起来确实像是编辑误读了编码,而不是文件没有"编码"。
- Those bytes, if present, must be ignored不是BOM也是零宽度不间断空格(zwnbs)吗?如果是这样的话,难道不应该把它解释成Unicode字符,然后用正确的编码把它写成该字符吗?Ignored似乎是在这里使用的错误术语。
将BOM放入UTF-8编码文件中至少有三个问题。
不包含文本的文件不再为空,因为它们始终包含物料清单。
在UTF-8的ASCII子集中保存文本的文件不再是ASCII文件,因为BOM不是ASCII,这使得一些现有的工具崩溃,用户可能无法替换这些遗留工具。
无法将多个文件连接在一起,因为每个文件的开头都有一个BOM。
而且,正如其他人所提到的,拥有一个BOM来检测某种东西是UTF-8,这既不充分也不必要:
- 这是不够的,因为一个任意的字节序列可能恰好从构成BOM的确切序列开始。
- 这是不必要的,因为您可以像读取UTF-8那样读取字节;如果读取成功,根据定义,它是有效的UTF-8。
- -每个树项目符号点中有1个无效逻辑。
- @干杯和我已经澄清了上述声明;它们是事实,没有逻辑。
- 在编辑了第1点和第2点之后,这两个点不再是正面的自相矛盾。这是一个进步。我将依次讨论每一点。
- 第1点"没有文本的文件不再是空的,因为它们总是包含bom",这(1)将OS文件系统级别与解释的内容级别相混淆,加上它(2)错误地假定使用bom时,必须在每个其他空文件中也放入bom。(1)的实际解决办法是不做(2)。从本质上讲,投诉减少到"可能不实际地将一个BOM放在一个空文件中,从而防止最容易检测到逻辑上为空的文件(通过检查文件大小)"。但好的软件应该能够处理它,因为它有一个目的。
- 第二点,"保存ASCII文本的文件不再是ASCII",这将把ASCII与UTF-8混为一谈。保存ASCII文本的UTF-8文件不是ASCII,而是UTF-8。同样,保存ASCII文本的UTF-16文件不是ASCII,而是UTF-16。等等。ASCII是一个7位单字节代码。UTF-8是ASCII的8位可变长度扩展。如果"工具崩溃"是因为>127个值,那么它们不适合8位的世界。一个简单的实际解决方案是,仅将ASCII文件与分解为非ASCII字节值的工具一起使用。一个可能更好的解决办法是抛弃那些不好用的工具。
- 重复第3点,"不可能将多个文件连接在一起,因为每个文件的开头都有一个BOM"是错误的。我可以将utf-8文件与bom连接起来,这显然是可能的。我想也许你的意思是Unix Land cat不会给你一个干净的结果,一个只有bom的结果。如果你的意思是,那么这是因为cat在字节级别工作,而不是在解释内容级别,并且以类似的方式,cat不能处理照片,比如说。不过,这并没有造成太大的伤害。这是因为BOM编码零宽度的不间断空格。
- 重新考虑最后的声明,"正如其他人所提到的,拥有一个BOM来检测某个东西是UTF-8是既不充分也不必要的。"是错误的。在某些情况下是不必要的,但在其他情况下是必要的。例如,VisualC++编译器在源代码文件开始时需要一个BOM,以便正确地识别其编码为UTF-8。
- 总之,由于这三点加上最后声明中的每一点都是错误的和/或严重误导性的,所以我坚持投反对票。我希望以上的解释是充分的。如果没有,那就问问。
- @干杯,谢谢。-如果这个答案是正确的。你只是指出了微软的错误。
- @从什么时候开始,SO声明中的自相矛盾就成了一些供应商的错误。哎呀。这个答案完全是胡说八道,每一句话,你的评论也是如此。投反对票。
- 如果没有BOM,就不能百分之百确定是否可以检测到它是UTF-8!检查每个字节是否小于128,如果不是,检查它是否是有效的UTF-8序列?好吧,听起来不错,但要知道第一个假设可能已经错了。如果文件是UTF-16编码的,并且只检查16位值的高字节和低字节,则可能会在高字节和低字节上找到小于127的值,但字可能仍然高于127!您甚至可以找到一个startbyte和正确的following byte,但这也可以是一个16位宽的以utf-16编码的字符值。
- @布莱迪:不过,通过增加一个物料清单,情况没有任何改善。
- 物料清单的另一个问题…正则表达式不将其识别为字符串的开头,甚至是行首
- 声明1和3错误。BOM实际上是Unicode字符U+FEFF -> ZERO WIDTH NO-BREAK SPACE。仅包含物料清单的文件不是空的,它包含一个普通(但不可见)字符。在一个文本文件中,您可以根据自己的喜好放置任意多个ZERO WIDTH NO-BREAK SPACE字符,就像其他字符一样。在某些脚本语言中,这种技术用于混淆源代码。
- 语句1和3(部分)错误。物料清单是Unicode字符ZERO WIDTH NO-BREAK SPACE。仅包含物料清单的文件不是空的,它包含一个普通(但不可见)字符。在文本文件中,您可以根据需要放置任意多个零宽不间断空格字符。然而,字节顺序标记(bom)常见问题解答说:在文件的中间[…]u+feff通常不应该出现。为了向后兼容,它应该被视为零宽度不间断空格(zwnbsp),然后是文件或字符串内容的一部分。
- @t请注意,答案可能有些正确,但从技术上讲,您的评论显然是错误的。对物料清单的处理并不特定于任何供应商。听起来好像你假设C++的多态类是一个POD(BOM是一个类似于虚拟指针的模拟实现细节),因此被意外的行为所困扰。那么,它肯定是你的bug,而不是C++。
这是一个有很多好答案的老问题,但有一点需要补充。
所有的答案都很笼统。我想补充的是,BOM使用的例子实际上会导致真正的问题,但很多人并不知道。
物料清单中断脚本
shell脚本、perl脚本、python脚本、ruby脚本、node.js脚本或任何其他需要由解释器运行的可执行文件-所有这些都以shebang行开始,看起来像是其中之一:
1 2 3 4
| #!/bin/sh
#!/usr/bin/python
#!/usr/local/bin/perl
#!/usr/bin/env node |
它告诉系统调用此类脚本时需要运行哪个解释器。如果脚本是以UTF-8编码的,那么可能会在开头包含一个BOM。但实际上是"!"字符不仅仅是字符。它们实际上是由两个ASCII字符组成的幻数。如果您在这些字符之前放置一些东西(如BOM),那么文件将看起来像是有一个不同的幻数,这可能会导致问题。
参见维基百科,文章:shebang,章节:魔力数字:
The shebang characters are represented by the same two bytes in
extended ASCII encodings, including UTF-8, which is commonly used for
scripts and other text files on current Unix-like systems. However,
UTF-8 files may begin with the optional byte order mark (BOM); if the
"exec" function specifically detects the bytes 0x23 and 0x21, then the
presence of the BOM (0xEF 0xBB 0xBF) before the shebang will prevent
the script interpreter from being executed. Some authorities recommend
against using the byte order mark in POSIX (Unix-like) scripts,[14]
for this reason and for wider interoperability and philosophical
concerns. Additionally, a byte order mark is not necessary in UTF-8,
as that encoding does not have endianness issues; it serves only to
identify the encoding as UTF-8. [emphasis added]
JSON中的BOM非法
见RFC 7159第8.1节:
Implementations MUST NOT add a byte order mark to the beginning of a JSON text.
在JSON中,BOM是冗余的
不仅在JSON中是非法的,还不需要确定字符编码,因为有更可靠的方法可以明确地确定在任何JSON流中使用的字符编码和结束地址(有关详细信息,请参见此答案)。
BOM中断JSON解析器
它不仅在JSON中是非法的,而且不需要,它实际上破坏了所有使用RFC 4627中提供的方法确定编码的软件:
确定JSON的编码和结尾,检查nul字节的前4个字节:
1 2 3 4 5
| 00 00 00 xx - UTF-32BE
00 xx 00 xx - UTF-16BE
xx 00 00 00 - UTF-32LE
xx 00 xx 00 - UTF-16LE
xx xx xx xx - UTF-8 |
现在,如果文件以BOM开头,它将如下所示:
1 2 3 4 5
| 00 00 FE FF - UTF-32BE
FE FF 00 xx - UTF-16BE
FF FE 00 00 - UTF-32LE
FF FE xx 00 - UTF-16LE
EF BB BF xx - UTF-8 |
注意:
utf-32be不是以三个nul开头的,因此无法识别
utf-32le第一个字节后面没有3个nuls,因此无法识别
UTF-16BE在前4个字节中只有1个nul,因此无法识别。
UTF-16LE在前4个字节中只有1个nul,因此无法识别。
根据实现的不同,所有这些可能被错误地解释为UTF-8,然后被错误地解释或拒绝为无效的UTF-8,或者根本无法识别。
另外,如果实现按照我的建议测试有效的JSON,它甚至会拒绝实际上编码为UTF-8的输入,因为它不会以ASCII字符<128开头,因为它应该按照RFC进行。
其他数据格式
JSON中的BOM不需要,是非法的,并且破坏了根据RFC正确工作的软件。当时不使用它应该是一种高尚的做法,但是,总是有人坚持使用bom、注释、不同的引用规则或不同的数据类型来破坏JSON。当然,如果你需要的话,任何人都可以自由使用boms或者其他任何东西——那就不要叫它json。
对于JSON以外的其他数据格式,请看一下它的实际外观。如果唯一的编码是utf-*并且第一个字符必须是小于128的ASCII字符,那么您已经拥有了确定数据的编码和结束地址所需的所有信息。即使将bom作为可选功能添加,也只会使其更加复杂和容易出错。
物料清单的其他用途
至于JSON或脚本之外的用法,我认为这里已经有了非常好的答案。我想添加更多关于脚本编写和序列化的详细信息,因为它是导致实际问题的BOM字符示例。
- 取代RFC4627的RFC7159实际上表明支持BOM可能并不那么邪恶。基本上,没有bom只是一个模棱两可的拼凑,因此不支持Unicode的旧Windows和Unix软件仍然可以处理utf-8。
- 听起来JSON需要更新才能支持它,Perl脚本、Python脚本、Ruby脚本、node.js也是如此。仅仅因为这些平台选择不包括支持,就不一定会破坏对BOM的使用。苹果已经试图杀死Adobe几年了,Adobe仍然存在。但这是一个有启发性的职位。
- @EricGrange,您似乎非常支持bom,但没有意识到这会使所有无所不在、普遍有用、最佳的最小"纯文本"格式成为pre-utf8过去的遗迹!在纯文本流中添加任何类型的(带内)头,根据定义,将强制协议应用于最简单的文本文件,使其不再是"最简单的"!为了什么利益?为了支持所有其他的,古老的CP编码也没有签名,所以您可能会把它们误认为是UTF-8?(顺便说一下,ASCII也是UTF-8。那么,也给他们一个清单?来吧!
What's different between UTF-8 and UTF-8 without BOM?
简短回答:在UTF-8中,BOM在文件开头被编码为字节EF BB BF。
长回答:
最初,预期unicode将以utf-16/ucs-2编码。物料清单是为此编码表单设计的。当您有两个字节的代码单元时,需要指明这两个字节的顺序,这样做的一个常见约定是在数据的开头将字符u+feff作为"字节顺序标记"。字符u+fffe是永久未分配的,因此它的存在可以用来检测错误的字节顺序。
UTF-8具有相同的字节顺序,而不管平台的端序如何,因此不需要字节顺序标记。但是,在从UTF-16转换为UTF-8的数据中可能会出现(字节序列EF BB FF),或者作为"签名"表示数据是UTF-8。
Which is better?
没有。正如MartinCote所回答的,Unicode标准不推荐使用它。它会导致不了解BOM的软件出现问题。
检测文件是否为UTF-8的更好方法是执行有效性检查。UTF-8对哪些字节序列是有效的有严格的规则,所以假阳性的概率可以忽略不计。如果一个字节序列看起来像UTF-8,那么它很可能是。
- 这也会使有效的UTF-8失效,其中只有一个错误的字节:/
- 1 RE"它导致了非BOM感知软件的问题",这对我来说从来都不是问题,相反,BOM的缺失会导致BOM感知软件(特别是VisualC++)出现问题。因此,这个声明是非常平台化的,是一个狭隘的Unix Land观点,但是在一般情况下,它被误导地呈现出来,就好像它适用一样。但事实并非如此。
- 不,UTF-8没有BOM。这个答案不正确。请参见Unicode标准。
- 当您只查看字节时,甚至可以认为您拥有一个纯ASCII文件。但这也可以是一个utf-16文件,在这里您必须查看单词而不是字节。现代的软件应该了解bom。如果检测到无效序列、可以使用较小序列的代码点或作为代理的代码点,仍然读取UTF-8可能会失败。对于UTF-16,如果存在孤立的代理,读取也可能失败。
带BOM的UTF-8更容易识别。我很难得出这个结论。我正在做一个项目,其中一个结果是一个csv文件,包括unicode字符。
如果保存的csv文件没有bom,excel会认为它是ansi,并显示乱码。一旦在前面添加了"ef bb bf"(例如,使用带有utf-8的记事本重新保存它,或使用带有bom的utf-8的记事本++重新保存它),Excel就会很好地打开它。
RFC 3629建议将BOM字符预处理为Unicode文本文件:"UTF-8,ISO 10646的转换格式",2003年11月网址:http://tools.ietf.org/html/rfc3629(最新信息见:http://www.herongyang.com/unicode/notepad-byte-order-mark-bom-feff-efbbbf.html)
- 感谢您提供这一极好的提示,以防有人创建供Excel使用的UTF-8文件。但在其他情况下,我还是会按照其他答案跳过BOM。
- 如果您创建的文件只包含ASCII,并且以后可能添加了非ASCII,那么它也很有用。我刚刚遇到了这样一个问题:需要utf8的软件,用一些数据创建文件供用户编辑。如果初始文件只包含ASCII,在某些编辑器中打开,然后保存,则以拉丁文1结尾,所有内容都将中断。如果我添加BOM,编辑器会检测到它是utf8,一切正常。
- +1对于RFC 3629参考
- 我发现了多个与编程相关的工具,它们要求BOM正确识别UTF-8文件。Visual Studio、SSMS、Souretree…。
- 您在哪里阅读了使用该RFC的BOM的建议?最多,有一个强烈的建议,在某些情况下不禁止这样做是困难的。
- Excel认为它是ANSI,并且显示出乱七八糟的地方,那么问题就在Excel中。
- RFC3629说它是无用的:UTF-8 having a single-octet encoding unit, this last function is useless and the BOM will always appear as the octet sequence EF BB BF.
- libreoffice calc在导入没有bom、制表符分隔的csv文件的utf时没有问题。它只是把它当作ASCII码。
bom倾向于在某个地方或某个地方蓬勃发展(没有双关语(sic))。当它繁荣时(例如,浏览器、编辑等无法识别),它会在文档开始时显示为奇怪的字符???(例如,HTML文件、JSON响应、RSS等),并导致类似最近奥巴马在Twitter上所说的编码问题这样的尴尬。
当它出现在难以调试的地方或者测试被忽略时,这是非常烦人的。所以最好避免它,除非你必须使用它。
- 是的,只是花了几个小时来识别一个由文件编码为UTF-8而不是没有BOM的UTF-8引起的问题。(这个问题只出现在IE7中,因此我陷入了一场相当激烈的追逐。我用了姜戈的"include"。)
- 未来的读者:请注意,我上面提到的tweet问题与bom没有严格的关系,但如果是,那么tweet也会以类似的方式出现混乱,但在tweet的开头。
- @用户984003不,问题是微软误导了你。它所称的utf-8不是utf-8。它所说的没有BOM的UTF-8就是真正的UTF-8。
- "sic"在你的"无意双关语"中添加了什么?
- @乔尔凡,我记不起来了,但我想双关语可能是故意的,尽管作者声称:)
Question: What's different between UTF-8 and UTF-8 without a BOM? Which is better?
以下是维基百科关于字节顺序标记(bom)的文章中的一些摘录,我相信这些摘录为这个问题提供了一个可靠的答案。
关于BOM和UTF-8的含义:
The Unicode Standard permits the BOM in UTF-8, but does not require
or recommend its use. Byte order has no meaning in UTF-8, so its
only use in UTF-8 is to signal at the start that the text stream is
encoded in UTF-8.
不使用物料清单的参数:
The primary motivation for not using a BOM is backwards-compatibility
with software that is not Unicode-aware... Another motivation for not
using a BOM is to encourage UTF-8 as the"default" encoding.
使用物料清单的参数:
The argument for using a BOM is that without it, heuristic analysis is
required to determine what character encoding a file is using.
Historically such analysis, to distinguish various 8-bit encodings, is
complicated, error-prone, and sometimes slow. A number of libraries
are available to ease the task, such as Mozilla Universal Charset
Detector and International Components for Unicode.
Programmers mistakenly assume that detection of UTF-8 is equally
difficult (it is not because of the vast majority of byte sequences
are invalid UTF-8, while the encodings these libraries are trying to
distinguish allow all possible byte sequences). Therefore not all
Unicode-aware programs perform such an analysis and instead rely on
the BOM.
In particular, Microsoft compilers and interpreters, and many
pieces of software on Microsoft Windows such as Notepad will not
correctly read UTF-8 text unless it has only ASCII characters or it
starts with the BOM, and will add a BOM to the start when saving text
as UTF-8. Google Docs will add a BOM when a Microsoft Word document is
downloaded as a plain text file.
有或没有物料清单,哪一个更好:
The IETF recommends that if a protocol either (a) always uses UTF-8,
or (b) has some other way to indicate what encoding is being used,
then it"SHOULD forbid use of U+FEFF as a signature."
我的结论是:
只有在与软件应用程序的兼容性是绝对必要的情况下才使用BOM。
另外请注意,尽管引用的维基百科文章指出,许多Microsoft应用程序依赖于BOM来正确检测UTF-8,但并非所有Microsoft应用程序都是如此。例如,@barlop指出,当使用带有utf-8&dagger;的windows命令提示符时,type和more等命令不希望出现BOM。如果存在物料清单,它可能会像其他应用程序一样有问题。
&dagger;chcp命令通过代码页65001支持UTF-8(不含BOM)。
- 我最好严格到没有物料清单。我发现.htaccess和gzip compression与utf-8 bom结合在一起会导致编码错误改变为在没有bom的情况下使用utf-8编码,下面给出一个解决问题的建议。
- "不使用BOM的另一个动机是鼓励将UTF-8作为"默认"编码。"——这是一个非常强大且有效的参数,以至于您实际上可以在那里停止回答!…;-o除非您对通用文本表示有更好的想法,否则就是。;)(我不知道你多大了,在预UTF8时代你要忍受多少年的痛苦(当时语言学家拼命地考虑甚至改变他们的字母表),但我可以告诉你,我们每一秒钟都会接近于消除所有古老的单字节的混乱,而不使用元数据编码,而不是"一个"是纯粹的快乐。)
- 另请参见有关如何添加物料清单(或其他内容)的注释。对于最简单的文本文件格式,"纯文本"意味着阻止最佳的通用文本编码格式成为"纯"和"简单"(即"overheadless")!…
我从另一个角度看待这个问题。我认为带有bom的utf-8更好,因为它提供了关于文件的更多信息。我只在遇到问题时才使用没有BOM的UTF-8。
我在我的页面上使用了多种语言(甚至西里尔文)很长一段时间,当文件保存时没有使用bom,我重新打开它们以便用编辑器进行编辑(如Cherouvim所指出的),一些字符已损坏。
请注意,当您尝试用UTF-8编码保存新创建的文件时,Windows的经典记事本会自动用BOM保存文件。
我个人保存服务器端脚本文件(.asp,.ini,.aspx)与bom和.html文件没有bom。
- 感谢您提供有关Windows经典记事本的精彩提示。我已经花了一些时间找到了完全一样的东西。我的结果是总是使用记事本++而不是Windows经典记事本。-)
- 你最好用玛迪特。如果您选择一个UTF-8字节序列而不是字节和字符之间的1:1基础,那么它是唯一一个以十六进制模式显示一个字符的编辑器。知道UTF-8文件的十六进制编辑器应该和madedit一样。
- @布莱迪,我认为你不需要一对一的,为了BOM。没关系,识别一个utf-8bom是efbbbf或fffe(如果读取错误,则为fffe)并不需要太多的时间。可以简单地删除这些字节。不过,为文件的其余部分创建一个映射也不错,而且还可以逐字节删除。
- @barlop如果文件的内容是utf-8编码的,为什么要删除utf-8 BOM?现代文本查看器、文本控件和文本编辑器可以识别BOM。UTF-8序列的一对一视图是没有意义的,因为N个字节产生一个字符。当然,文本编辑器或十六进制编辑器应该允许删除任何字节,但这可能导致无效的UTF-8序列。
- @带有bom的brighty utf-8是一种编码,没有bom的utf-8是一种编码。命令提示使用不带bom的utf8。因此,如果您有一个utf8文件,那么运行命令chcp 65001以获得utf8支持,它是不带BOM的utf8。如果执行type myfile,则只有在没有物料清单的情况下才会正确显示。如果您执行echo aaa>a.a或echo ???>a.a将字符输出到文件A.A,并且您有CHCP 65001,它将不输出BOM。
在bom上的维基百科页面底部引用:http://en.wikipedia.org/wiki/byte-order_mark_cite_note-2
"Use of a BOM is neither required nor recommended for UTF-8, but may be encountered in contexts where UTF-8 data is converted from other encoding forms that use a BOM or where the BOM is used as a UTF-8 signature"
- 您是否有这样的例子:软件根据其编码的前一个编码是否有BOM,决定是否使用带/不带BOM的UTF-8?!这似乎是一个荒谬的说法
只有当文件实际包含一些非ASCII字符时,带有BOM的UTF-8才有帮助。如果它包含在其中并且没有任何内容,那么它可能会破坏旧的应用程序,否则会将该文件解释为纯ASCII。当这些应用程序遇到非ASCII字符时,它们肯定会失败,因此在我看来,只有当文件可以并且应该不再被解释为纯ASCII时,才应该添加BOM。
编辑:我只想澄清一下,我更喜欢完全没有这个BOM,如果一些旧的垃圾把它弄坏了,就把它添加进去,替换旧的应用程序是不可行的。
不要做任何事情,除了UTF8的BOM。
没有bom的utf-8没有bom,这并没有比带有bom的utf-8更好,除非文件的使用者需要知道(或者从中受益)文件是否是utf-8编码的。
BOM通常有助于确定编码的结束语,这在大多数用例中是不需要的。
此外,对于那些不了解或不关心它的消费者来说,BOM可能是不必要的噪音/痛苦,并且可能导致用户混淆。
- "这对UTF-8毫无用处,因为它是每个字形8位的。"呃…不,只有ASCII-7符号是8位的UTF-8。除此之外的任何数据都将是16、24或32位。
- "BOM通常有助于确定编码的结尾,这对于大多数用例来说是不需要的。"…无论用例如何,endianness都不适用于utf-8
应该注意的是,对于某些文件,即使在Windows上也不能有BOM。例如SQL*plus或VBScript文件。如果这样的文件包含一个物料清单,那么当您试图执行它们时就会出错。
当您想显示以UTF-8编码的信息时,可能不会遇到问题。例如,将HTML文档声明为UTF-8,您将在浏览器中显示文档正文中包含的所有内容。
但当我们在Windows或Linux上拥有文本、csv和xml文件时,情况并非如此。
例如,Windows或Linux中的文本文件是最容易想到的事情之一,它不是(通常)UTF-8。
将其保存为XML并声明为UTF-8:
1
| <?xml version="1.0" encoding="UTF-8"?> |
即使声明为UTF-8,它也不会正确显示(不会被读取)。
我有一系列包含法语字母的数据,这些数据需要保存为XML进行联合。不需要从头创建UTF-8文件(更改IDE和"创建新文件"中的选项),也不需要在文件开头添加BOM
1
| $file="\xEF\xBB\xBF".$string; |
我无法将法语字母保存在XML文件中。
- 在XML中,我认为您应该将文件保存为ASCII并使用实体。
- 我知道这是一个古老的答案,但我只想说这是错误的。Linux上的文本文件(不能代表其他unix)通常是/are/utf-8。
一个实际的区别是,如果您为Mac OS X编写一个shell脚本并将其保存为纯UTF-8,您将得到以下响应:
1
| #!/bin/bash: No such file or directory |
响应shebang行,指定要使用的外壳:
如果您保存为utf-8,那么没有bom(比如bbedit)都会很好。
- 这是因为微软已经改变了标准的含义。utf-8没有bom:他们创建了Microsoft utf-8,它在数据流前面插入了一个假的bom,然后告诉您不,这实际上是utf-8。不是这样。它只是在延伸和腐化。
这个问题已经有一百万个答案,其中许多答案都很好,但我想试着澄清什么时候应该或不应该使用BOM。
如前所述,在确定字符串是否为UTF-8时使用UTF BOM(字节顺序标记)是一种有根据的猜测。如果有合适的元数据可用(如charset="utf-8"),那么您就已经知道应该使用什么了,否则您需要进行测试并做出一些假设。这涉及到检查字符串来自的文件是否以十六进制字节代码ef bb bf开头。
如果找到了与utf-8bom对应的字节代码,那么这个概率就足够高,可以假设它是utf-8,您可以从那里开始。然而,当被迫做出这种猜测时,在阅读时进行额外的错误检查仍然是一个好主意,以防出现混乱。如果输入的源代码绝对不应该是UTF-8,那么您应该只假设一个BOM不是UTF-8(即拉丁语-1或ANSI)。但是,如果没有BOM,您可以通过对编码进行验证来简单地确定它是否应该是UTF-8。
为什么不推荐物料清单?
不支持Unicode或不兼容的软件可能会假定它是拉丁语1或ANSI,并且不会从字符串中去掉BOM,这显然会导致问题。
这不是真正需要的(只需检查内容是否兼容,并在找不到兼容编码时始终使用UTF-8作为回退)
什么时候用物料清单编码?
如果您不能以任何其他方式记录元数据(通过charset标记或文件系统meta),以及像boms一样使用的程序,则应该使用bom进行编码。这在Windows上尤其如此,在Windows中,没有BOM的任何东西通常都被认为是在使用遗留代码页。BOM告诉像Office这样的程序,是的,这个文件中的文本是Unicode;下面是使用的编码。
归根结底,我唯一真正有问题的文件是csv。根据程序的不同,它要么必须,要么不能有一个BOM。例如,如果您在Windows上使用Excel2007+,那么如果您想顺利打开它,而不必借助于导入数据,那么必须使用BOM对其进行编码。
如上所述,带有BOM的UTF-8可能会导致不知道BOM(或兼容)的软件出现问题。我曾经用基于Mozilla的Kompozer编辑过编码为utf-8+bom的HTML文件,因为客户机需要WYSIWYG程序。
保存时布局总是会被破坏。我花了些时间才解决这个问题。这些文件在Firefox中很好地工作,但是在Internet Explorer中又显示了一个CSS的怪癖,破坏了布局。在处理链接的CSS文件数小时后,我发现Internet Explorer不喜欢bomfed HTML文件。再也不要了。
另外,我在维基百科上发现了这个:
The shebang characters are represented by the same two bytes in extended ASCII encodings, including UTF-8, which is commonly used for scripts and other text files on current Unix-like systems. However, UTF-8 files may begin with the optional byte order mark (BOM); if the"exec" function specifically detects the bytes 0x23 0x21, then the presence of the BOM (0xEF 0xBB 0xBF) before the shebang will prevent the script interpreter from being executed. Some authorities recommend against using the byte order mark in POSIX (Unix-like) scripts,[15] for this reason and for wider interoperability and philosophical concerns
Unicode字节顺序标记(BOM)常见问题解答提供了一个简明的答案:
Q: How I should deal with BOMs?
A: Here are some guidelines to follow:
A particular protocol (e.g. Microsoft conventions for .txt files) may require use of the BOM on certain Unicode data streams, such as
files. When you need to conform to such a protocol, use a BOM.
Some protocols allow optional BOMs in the case of untagged text. In those cases,
-
Where a text data stream is known to be plain text, but of unknown encoding, BOM can be used as a signature. If there is no BOM,
the encoding could be anything.
-
Where a text data stream is known to be plain Unicode text (but not which endian), then BOM can be used as a signature. If there
is no BOM, the text should be interpreted as big-endian.
Some byte oriented protocols expect ASCII characters at the beginning of a file. If UTF-8 is used with these protocols, use of the
BOM as encoding form signature should be avoided.
Where the precise type of the data stream is known (e.g. Unicode big-endian or Unicode little-endian), the BOM should not be used. In
particular, whenever a data stream is declared to be UTF-16BE,
UTF-16LE, UTF-32BE or UTF-32LE a BOM must not be used.
来自http://en.wikipedia.org/wiki/byte-order_mark:
The byte order mark (BOM) is a Unicode
character used to signal the
endianness (byte order) of a text file
or stream. Its code point is U+FEFF.
BOM use is optional, and, if used,
should appear at the start of the text
stream. Beyond its specific use as a
byte-order indicator, the BOM
character may also indicate which of
the several Unicode representations
the text is encoded in.
始终在文件中使用BOM将确保它始终在支持UTF-8和BOM的编辑器中正确打开。
我对缺少BOM的真正问题是。假设我们有一个文件,其中包含:
在大多数编辑器中,如果没有BOM,这将作为ANSI打开。所以这个文件的另一个用户打开它并附加一些本机字符,例如:
哎呀。。。现在文件仍在ANSI中,猜猜看,"αβγ"不占6个字节,而是3个字节。这不是UTF-8,这会在以后的开发链中引起其他问题。
- 确保伪字节出现在不了解BOM的软件的开头。是的。
- @RomainMuller:例如,当您试图在BOM之后发送标题时,php 5将抛出"不可能"的错误。
- αβγ不是ASCII,但可以出现在8位ASCII基础编码中。使用bom会禁用utf-8的benafit,它与ascii兼容(在使用纯ascii的lagacy应用程序中工作的能力)。
- 这是错误的答案。前面有一个bom的字符串完全是另一回事。它不应该在那里,只是把一切都搞砸了。
- 在大多数编辑器中,如果没有BOM,这将作为ANSI打开。我完全同意。如果发生这种情况,如果处理正确的代码页,您就很幸运了,但实际上这只是一个猜测,因为代码页不是文件的一部分。BOM是。
如果在HTML文件中使用UTF-8,或者在同一页中使用塞尔维亚西里尔文、塞尔维亚拉丁语、德语、匈牙利语或其他外来语言,则带BOM的UTF更好。这是我的观点(计算机和IT行业30年)。
- 我也觉得这是真的。如果您使用前255个ASCII集之外的字符,而忽略了BOM,浏览器会将其解释为ISO-8859-1,您会得到乱码字符。根据上面的答案,这显然是浏览器供应商在没有检测到BOM时做了错误的事情。但是,除非您在Microsoft Edge/Mozilla/Webkit/Blink工作,否则您别无选择,只能处理这些应用程序的缺陷。