- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
byte order mark (BOM)对于 UTF-8是 EF BB BF
,如 section 23.8 of the Unicode 9 中所述规范(搜索“签名”)。
Java 中的许多解决方案都只是简单的一行代码:
replace("\uFEFF", "")
我不明白为什么会这样。
这是我的测试代码。我在调用 String#replace
后检查了二进制文件,发现 EF BB BF 确实被删除了。看这个code run live at IdeOne.com .
太神奇了。为什么会这样?
@Test
public void shit() throws Exception{
byte[] b = new byte[]{-17,-69,-65, 97,97,97};//EF BB BF 61 61 61
char[] c = new char[10];
new InputStreamReader(new ByteArrayInputStream(b),"UTF-8").read(c);
byte[] bytes = new StringBuilder().append(c).toString().replace("\uFEFF", "").getBytes();//
for(byte bt: bytes){//61 61 61, we can see EF BB BF is indeed removed
System.out.println(bt);
}
}
最佳答案
原因是 unicode 文本应以字节顺序标记开头(UTF-8 除外,它不是推荐强制性[1])。
来自维基百科
The byte order mark (BOM) is a Unicode character, U+FEFF BYTE ORDER MARK (BOM), whose appearance as a magic number at the start of a text stream ...
...
The BOM is encoded in the same scheme as the rest of the document ...
这意味着这个特殊字符 (\uFEFF
) 也必须以 UTF-8 编码。
UTF-8 可以将 Unicode 代码点编码为一到四个字节。
0xxx xxxx
110x xxxx
表示编码由两个字节表示,连续字节始终以 10xx xxxx
开头(x
位可用于代码点)U+0000 - U+007F
范围内的码点可以用一个字节编码。U+0080 - U+07FF
范围内的代码点可以用两个字节编码。U+0800 - U+FFFF
范围内的代码点可以用三个字节编码。
详细解释在Wikipedia
对于 BOM,我们需要三个字节。
hex FE FF
binary 11111110 11111111
用UTF-8编码
pattern for three byte encoding 1110 xxxx 10xx xxxx 10xx xxxx
the bits of the code point 1111 11 1011 11 1111
result 1110 1111 1011 1011 1011 1111
in hex EF BB BF
EF BB BF
听起来很熟悉。 ;-)
字节序列 EF BB BF
就是以 UTF-8 编码的 BOM。
由于字节顺序标记对 UTF-8 没有意义,因此在 Java 中未使用。
将 BOM 字符编码为 UTF-8
jshell> "\uFEFF".getBytes("UTF-8")
$1 ==> byte[3] { -17, -69, -65 } // EF BB BF
因此,当读取文件时,字节序列被解码为 \uFEFF
。
用于编码,例如UTF-16 添加BOM
jshell> " ".getBytes("UTF-16")
$2 ==> byte[4] { -2, -1, 0, 32 } // FE FF + the encoded SPACE
[1] 引自:http://www.unicode.org/versions/Unicode9.0.0/ch23.pdf
Although thereare never any questions of byte order with UTF-8 text, this sequence can serve as signaturefor UTF-8 encoded text where the character set is unmarked. As with a BOM in UTF-16,this sequence of bytes will be extremely rare at the beginning of text files in other characterencodings.
关于java - 为什么UTF-8 BOM字节efbbbf可以换成\ufeff?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54247407/
我是一名优秀的程序员,十分优秀!