我在读评论到答案通过@Esailija我的一个疑问,
ISO-8859-1是唯一的编码,以充分保留原来的二进制数据,以精确的字节< - >码点匹配
我也看了这个答案由@AaronDigulla说:
在Java中,ISO-8859-1(又名ISO-Latin1的)为1:1的映射
我需要这方面的一些见解。 这将失败(如图所示这里 ):
// \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
指定 ) -链接到源,或者JSL将是很好。 它是具有这种性质的唯一编码? - 这是否与
ISO-8859-1
作为默认默认 ?
又见这个问题从其他字符集漂亮的反例。
"\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#或其他)没有关系。
这里有一个维基百科的参考声称,每一个字节覆盖:
1992年,IANA注册的字符映射ISO_8859-1:1987年,更常用的ISO-8859-1其首选MIME名称已知的(注意:在ISO 8859-1额外的连字符),ISO 8859-1的一个超集,用于使用互联网上。 此地图经由每一个可能的8位值分配C0和C1控制字符添加到未分配的代码值从而为256个字符。
(重点煤矿)
对于编码保留原始的二进制数据,它需要每一个独特的字节序列映射到一个独特的字符序列。
这排除了所有多字节编码(UTF-8/16/32,移位-JIS,BIG5等)因为不是每个字节序列是在其中有效,从而将解码的一些替换字符(通常?或)。 有没有办法从什么导致了替换字符已被解码后的字符串来告诉。
另一种选择是忽略无效字节,但这也意味着无限不同的字节序列进行解码,以相同的字符串。 你可以像使用字符串中的十六进制编码代替无效字节"0xFF"
。 有没有办法判断合法解码原来的字节"0xFF"
,这样也不行。
这使得8位编码,其中每一个序列只是一个单字节。 单字节是有效的,如果有它的映射。 但许多8位编码有洞,不编码256个不同的字符。
要保留原始二进制数据,则需要8位编码,编码256个不同的字符。 ISO-8859-1是不是在这个独特的。 但是,它的独特之处,在于解码码点的值也是字节的值它是从解码。
所以,你必须解码字符串,编码的字节,那么它始终是
(byte)str.charAt(i) == bytes[i]
对于任意的二进制数据,其中str
是new String(bytes, "ISO-8859-1")
和bytes
是一个byte[]
它也没有任何与Java。 我不知道他有什么意见意味着,这些字符编码不是编程语言的特性。