我在comment读到了@Esailija对我的一个问题的回答
ISO-8859-1是唯一完全保留原始二进制数据的编码,精确字节< - >代码点匹配
我也在@AaronDigulla的answer中读到:
在Java中,ISO-8859-1(a.k.a ISO-Latin1)是1:1的映射
我需要对此有所了解。这将失败(如图here所示):
// \u00F6 is ö
System.out.println(Arrays.toString("\u00F6".getBytes("utf-8")));
// prints [-61, -74]
System.out.println(Arrays.toString("\u00F6".getBytes("ISO-8859-1")));
// prints [-10]
ISO-8859-1
的字节保留行为) 指定的 em> - 链接到源,或者JSL会很好。它是唯一具有此属性的编码吗?ISO-8859-1
成为default default?另请参阅this question以获取其他字符集的精彩计数器示例。
答案 0 :(得分:12)
"\u00F6"
不是字节数组。它是一个包含单个字符的字符串。改为执行以下测试:
public static void main(String[] args) throws Exception {
byte[] b = new byte[] {(byte) 0x00, (byte) 0xf6};
String s = new String(b, "ISO-8859-1"); // decoding
byte[] b2 = s.getBytes("ISO-8859-1"); // encoding
System.out.println("Are the bytes equal : " + Arrays.equals(b, b2)); // true
}
要检查任何字节是否为真,只需通过所有字节改进代码:
public static void main(String[] args) throws Exception {
byte[] b = new byte[256];
for (int i = 0; i < b.length; i++) {
b[i] = (byte) i;
}
String s = new String(b, "ISO-8859-1");
byte[] b2 = s.getBytes("ISO-8859-1");
System.out.println("Are the bytes equal : " + Arrays.equals(b, b2));
}
ISO-8859-1是标准编码。所以使用的语言(Java,C#或其他)并不重要。
这是一个Wikipedia reference声称每个字节都被覆盖:
1992年,IANA注册了字符映射ISO_8859-1:1987,更常见的是其首选的MIME名称ISO-8859-1(请注意ISO 8859-1的额外连字符),ISO 8859的超集 - 1,用于互联网。此映射将C0和C1控制字符分配给未分配的代码值,从而通过每个可能的8位值提供256个字符。
(强调我的)
答案 1 :(得分:4)
对于保留原始二进制数据的编码,需要将每个唯一字节序列映射到唯一字符序列。
这排除了所有多字节编码(UTF-8/16/32,Shift-Jis,Big5等),因为并非每个字节序列都有效 因此会解码为一些替换字符(通常是?或 )。没有办法从字符串中分辨出什么原因 解码后的替换字符。
另一个选择是忽略无效字节但这也意味着无限不同
字节序列解码为相同的字符串。您可以使用十六进制编码替换无效字节
在像"0xFF"
这样的字符串中。没有办法判断原始字节是否合法解码
到"0xFF"
所以这也不起作用。
这留下了8位编码,其中每个序列只是一个字节。单字节有效 如果有它的映射。但是许多8位编码都有漏洞,不能编码256个不同的字符。
要保留原始二进制数据,您需要编码256个不同字符的8位编码。 ISO-8859-1 在这方面不是独一无二的。但它的独特之处在于,解码后的代码点的值也是字节的值 它是从。解码的。
所以你有解码后的字符串和编码字节,那么它总是
(byte)str.charAt(i) == bytes[i]
表示str
为new String(bytes, "ISO-8859-1")
且bytes
的任意二进制数据
是byte[]
。
它也与Java无关。我不知道他的评论意味着什么,这些是字符编码的属性,而不是编程语言。