sim*_*ple 783 unicode byte-order-mark utf-8 character-encoding
没有BOM的 UTF-8和UTF-8有什么不同?哪个更好?
Mar*_*ote 738
UTF-8 BOM是文本流(EF BB BF)开头的字节序列,允许读者更可靠地猜测文件是否以UTF-8编码.
通常,BOM用于表示编码的字节顺序,但由于字节顺序与UTF-8无关,因此BOM不是必需的.
根据Unicode标准,不建议使用UTF-8文件的BOM:
2.6编码方案
...对于UTF-8既不要求也不建议使用BOM,但在使用BOM的其他编码形式或将BOM用作UTF-8签名的UTF-8数据转换的上下文中可能会遇到.有关详细信息,请参见第16.8节 " 特价 "中的"字节顺序标记"小节.
pae*_*bal 229
其他优秀的答案已经回答:
EF BB BF但是,作为附加信息,如果字符串是以UTF-8编码的话,UTF-8的BOM可能是一种"闻"的好方法......或者它可能是任何其他编码中的合法字符串......
例如,数据[EF BB BF 41 42 43]可以是:
因此,虽然通过查看第一个字节来识别文件内容的编码可能很酷,但您不应该依赖于此,如上面的示例所示
编码应该是已知的,而不是神圣的.
J P*_*J P 125
将BOM放入UTF-8编码文件中至少存在三个问题.
并且,正如其他人所提到的那样,使用BOM来检测某些东西是UTF-8既不充分也不必要:
rsp*_*rsp 73
这是一个很老的问题,有许多好的答案,但应该添加一件事.
所有答案都很一般.我想添加的是实际导致实际问题的BOM使用示例,但很多人不了解它.
Shell脚本,Perl脚本,Python脚本,Ruby脚本,Node.js脚本或任何其他需要由解释器运行的可执行文件 - 都以shebang行开头,看起来像其中之一:
#!/bin/sh
#!/usr/bin/python
#!/usr/local/bin/perl
#!/usr/bin/env node
Run Code Online (Sandbox Code Playgroud)
它告诉系统在调用这样的脚本时需要运行哪个解释器.如果脚本以UTF-8编码,则可能会在开头包含BOM.但实际上是"#!" 字符不仅仅是字符.它们实际上是一个神奇的数字,恰好由两个ASCII字符组成.如果您在这些字符之前放置了某些内容(如BOM),那么该文件看起来会有不同的幻数,这可能会导致问题.
参见维基百科,文章:Shebang,部分:幻数:
shebang字符由扩展ASCII编码中的相同两个字节表示,包括UTF-8,它通常用于当前类Unix系统上的脚本和其他文本文件.但是,UTF-8文件可以以可选的字节顺序标记(BOM)开头; 如果"exec"函数专门检测到字节0x23和0x21,那么在shebang之前存在BOM(0xEF 0xBB 0xBF)将阻止脚本解释器被执行.由于这个原因以及更广泛的互操作性和哲学问题,一些权威机构建议不要在POSIX(类Unix)脚本中使用字节顺序标记[14].另外,在UTF-8中不需要字节顺序标记,因为该编码没有字节顺序问题; 它仅用于将编码标识为UTF-8.[强调补充]
请参阅RFC 7159,第8.1节:
实现绝不能在JSON文本的开头添加字节顺序标记.
它不仅在JSON中是非法的,而且还不需要确定字符编码,因为有更可靠的方法可以明确地确定任何JSON流中使用的字符编码和字节序(有关详细信息,请参阅此答案).
它不仅在JSON中是非法的而且不是必需的,它实际上打破了使用RFC 4627中提供的方法确定编码的所有软件:
确定JSON的编码和字节顺序,检查NUL字节的前4个字节:
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
Run Code Online (Sandbox Code Playgroud)
现在,如果文件以BOM开头,它将如下所示:
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
Run Code Online (Sandbox Code Playgroud)
注意:
根据实现情况,所有这些都可能被错误地解释为UTF-8,然后被误解为或被拒绝为无效的UTF-8,或根本无法识别.
此外,如果实现测试有效的JSON,我建议,它甚至会拒绝确实编码为UTF-8的输入,因为它不是以ASCII字符<128开头,因为它应该根据RFC.
不需要JSON中的BOM,这是违法的,并且会破坏根据RFC正常工作的软件.它应该是一个没有使用它的nobrainer然而,总有人坚持使用BOM,注释,不同的引用规则或不同的数据类型来破坏JSON.当然,如果你需要的话,任何人都可以自由地使用BOM或其他东西 - 只是不要把它称为JSON.
对于除JSON之外的其他数据格式,请看看它的外观.如果唯一的编码是UTF-*且第一个字符必须是低于128的ASCII字符,那么您已经拥有了确定数据的编码和字节序所需的所有信息.即使作为可选功能添加BOM也只会使其更复杂且容易出错.
至于JSON或脚本之外的用途,我认为这里已有很好的答案.我想添加更详细的脚本和序列化信息,因为它是导致实际问题的BOM字符的一个例子.
dan*_*n04 48
没有BOM的UTF-8和UTF-8有什么不同?
简答:在UTF-8中,BOM被编码为EF BB BF文件开头的字节.
答案很长:
最初,预计Unicode将以UTF-16/UCS-2编码.BOM是为此编码表单设计的.当你有2字节的代码单元时,有必要指出这两个字节在哪个顺序,这样做的一个通用约定是在数据的开头包含字符U + FEFF作为"字节顺序标记".字符U + FFFE永久未分配,因此可以使用它的存在来检测错误的字节顺序.
无论平台字节顺序如何,UTF-8都具有相同的字节顺序,因此不需要字节顺序标记.但是,它可能发生(作为字节序列EF BB FF)从UTF-16转换为UTF-8的数据,或作为"签名"表示数据是UTF-8.
哪个更好?
没有.正如Martin Cote回答的那样,Unicode标准不推荐它.它会导致非BOM感知软件出现问题.
检测文件是否为UTF-8的更好方法是执行有效性检查.UTF-8对哪些字节序列有效具有严格的规则,因此误报的概率可以忽略不计.如果字节序列看起来像UTF-8,它可能是.
Hel*_*man 29
可以更好地识别带有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)
Hal*_*gür 17
在某个地方,某些地方,BOM往往会繁荣(没有双关语意图(sic)).当它蓬勃发展时(例如,浏览器,编辑器等无法识别),它会在文档开头显示为奇怪的字符(例如,HTML文件,JSON响应,RSS等)并导致像奥巴马在推特上谈论的最近编码问题那样的尴尬.
当它出现在难以调试的地方或者忽略测试时,它会非常烦人.因此,除非必须使用它,否则最好避免使用它.
Dav*_*dRR 16
问题:没有BOM的UTF-8和UTF-8有什么不同?哪个更好?
以下是关于字节顺序标记(BOM)的维基百科文章的一些摘录,我相信这个问题可以为这个问题提供一个可靠的答案.
关于BOM和UTF-8的含义:
Unicode标准允许BOM的UTF-8 ,但不要求或建议其使用.字节顺序在UTF-8中没有意义,因此它在UTF-8中的唯一用途是在开始时发信号通知文本流以UTF-8编码.
不 使用BOM的参数:
不使用BOM的主要动机是向后兼容不支持Unicode的软件......不使用BOM的另一个动机是鼓励UTF-8作为"默认"编码.
参数 FOR 使用BOM:
使用BOM的论点是,没有它,需要启发式分析来确定文件使用的字符编码.历史上,用于区分各种8位编码的这种分析是复杂的,容易出错的,并且有时是慢的.许多库可用于简化任务,例如Mozilla Universal Charset Detector和International Components for Unicode.
程序员错误地认为检测UTF-8同样困难(这不是因为绝大多数字节序列都是无效的UTF-8,而这些库试图区分的编码允许所有可能的字节序列).因此,并非所有支持Unicode的程序都执行此类分析,而是依赖于BOM.
特别是,Microsoft编译器和解释器以及Microsoft Windows上的许多软件(如记事本)将无法正确读取UTF-8文本,除非它只有ASCII字符或以BOM开头,并且在保存时会添加BOM文字为UTF-8.当Microsoft Word文档作为纯文本文件下载时,Google文档将添加BOM.
哪个更好, 有 或 没有 BOM:
在IETF建议,如果一个协议或者(a)始终使用UTF-8,或(b)具有一些其它方式来指示正在使用什么编码,然后将其"应该禁止使用U + FEFF作为签名".
我的结论:
仅当与软件应用程序的兼容性绝对必要时才使用BOM .
另请注意,虽然引用的维基百科文章表明许多Microsoft应用程序依赖于BOM来正确检测UTF-8,但并非所有 Microsoft应用程序都是如此.例如,正如指出的@barlop,使用带有UTF-8的Windows命令提示符时†,命令等type和more不希望的BOM存在.如果BOM 是本,它可以是有问题的,因为它是用于其他应用.
†该chcp命令通过代码页65001提供对UTF-8(无 BOM)的支持.
没有BOM的UTF-8没有BOM,除了当文件的消费者需要知道(或将从知道中获益)该文件是否是UTF-8编码时,它没有比具有BOM的UTF-8更好.或不.
BOM通常用于确定编码的字节顺序,这在大多数用例中都不是必需的.
此外,对于那些不了解或不关心它的消费者来说,BOM可能是不必要的噪音/痛苦,并且可能导致用户混淆.
在BOM的维基百科页面底部引用:http://en.wikipedia.org/wiki/Byte-order_mark#cite_note-2
"对于UTF-8既不要求也不建议使用BOM,但在从使用BOM的其他编码形式或将BOM用作UTF-8签名的UTF-8数据转换的上下文中可能会遇到"
带BOM的UTF-8仅在文件实际包含一些非ASCII字符时才有用.如果它包含但没有,那么它可能会破坏旧文件,否则会将文件解释为纯ASCII.这些应用程序在遇到非ASCII字符时肯定会失败,所以在我看来,只有当文件可以而且不应该被解释为纯ASCII时才应添加BOM.
编辑:只是想明确表示我更喜欢根本没有BOM,如果一些旧的垃圾破坏了它就添加它,并且替换旧的应用程序是不可行的.
不要期望UTF8的BOM.
这个问题已经有一百万个答案了,其中很多都很好,但我想尝试澄清何时应该或不应该使用BOM.
如上所述,UTF BOM(字节顺序标记)在确定字符串是否为UTF-8时的任何使用都是受过教育的猜测.如果有适当的元数据(如charset="utf-8"),那么你已经知道你应该使用什么,但是否则你需要测试并做出一些假设.这涉及检查字符串来自的文件是否以十六进制字节代码EF BB BF开头.
如果找到对应于UTF-8 BOM的字节代码,则概率足够高以假设它是UTF-8,并且您可以从那里开始.然而,当被迫做出这种猜测时,在阅读时进行额外的错误检查仍然是一个好主意,以防万一出现乱码.如果输入肯定不应该是基于它的源的UTF-8,那么您应该只假设BOM不是UTF-8(即latin-1或ANSI).但是,如果没有BOM,您可以通过验证编码来确定它是否应该是UTF-8.
如果您无法以任何其他方式(通过字符集标记或文件系统元数据)记录元数据,以及正在使用的程序(如BOM),则应使用BOM进行编码.在Windows上尤其如此,其中通常假定没有BOM的任何内容都使用遗留代码页.BOM告诉像Office这样的程序,是的,这个文件中的文本是Unicode; 这是使用的编码.
归结到它,我遇到的唯一问题是CSV.根据程序的不同,它必须或者必须没有BOM.例如,如果您在Windows上使用Excel 2007+,则必须使用BOM进行编码,如果您想要平滑打开它而不必使用导入数据.
小智 6
我从不同的角度看待这个问题.我认为带有BOM的UTF-8更好,因为它提供了有关该文件的更多信息.如果我遇到问题,我只使用没有BOM的UTF-8.
我在我的页面上使用多种语言(甚至是西里尔语)很长一段时间,当文件保存而没有BOM时,我重新打开它们以便使用编辑器进行编辑(如cherouvim所述),某些字符已损坏.
请注意,当您尝试使用UTF-8编码保存新创建的文件时,Windows的经典记事本会自动保存带有BOM的文件.
我个人使用没有BOM的BOM和.html文件保存服务器端脚本文件(.asp,.ini,.aspx).
如果要显示以UTF-8编码的信息,可能不会遇到问题.例如,将HTML文档声明为UTF-8,您将在浏览器中显示包含在文档正文中的所有内容.
但是,当我们在Windows或Linux上拥有文本,CSV和XML文件时,情况并非如此.
例如,Windows或Linux中的文本文件,可以想象的最简单的事情之一,它(通常)不是UTF-8.
将其另存为XML并将其声明为UTF-8:
<?xml version="1.0" encoding="UTF-8"?>
Run Code Online (Sandbox Code Playgroud)
即使它被声明为UTF-8,它也不会正确显示(不会被读取).
我有一串包含法语字母的数据,需要将其保存为XML以进行联合.无需从头开始创建UTF-8文件(更改IDE中的选项和"创建新文件")或在文件开头添加BOM
$file="\xEF\xBB\xBF".$string;
Run Code Online (Sandbox Code Playgroud)
我无法将法语字母保存在XML文件中.
一个实际的区别是,如果你为Mac OS X编写一个shell脚本并将其保存为普通的UTF-8,你将得到响应:
#!/bin/bash: No such file or directory
Run Code Online (Sandbox Code Playgroud)
响应shebang行指定您要使用的shell:
#!/bin/bash
Run Code Online (Sandbox Code Playgroud)
如果你保存为UTF-8,那么没有BOM(比如在BBEdit中)都会很好.
Unicode字节顺序标记 (BOM) 常见问题解答提供了一个简洁的答案:
问:我应该如何处理 BOM?
答:以下是一些需要遵循的准则:
特定协议(例如 Microsoft 对 .txt 文件的约定)可能需要在某些 Unicode 数据流(例如文件)上使用 BOM。当您需要遵守此类协议时,请使用 BOM。
某些协议允许在未标记文本的情况下使用可选的 BOM。在这些情况下,
在已知文本数据流是纯文本但编码未知的情况下,可以将 BOM 用作签名。如果没有 BOM,则编码可以是任何内容。
如果已知文本数据流是纯 Unicode 文本(但不知道是哪种字节序),则可以将 BOM 用作签名。如果没有 BOM,则文本应解释为 big-endian。
一些面向字节的协议要求在文件开头使用 ASCII 字符。如果 UTF-8 与这些协议一起使用,则应避免使用 BOM 作为编码表单签名。
如果数据流的精确类型已知(例如 Unicode big-endian 或 Unicode little-endian),则不应使用 BOM。特别是,当数据流被声明为 UTF-16BE、UTF-16LE、UTF-32BE 或 UTF-32LE 时,不得使用 BOM。
| 归档时间: |
|
| 查看次数: |
539130 次 |
| 最近记录: |