Java中的ISO-8859-1编码是二进制安全的吗?

时间:2016-01-14 09:45:20

标签: java character-encoding

如果我使用ISO-8859-1编码将二进制流读入字符串,然后将其转换回二进制流,我是否总能得到完全相同的字节?如果没有,我什么时候不会得到相同的字节?

public byte[] toStringAndBack(byte[] binaryData) throws Exception {
    String s = new String(binaryData, "ISO-8859-1");
    return s.getBytes("ISO-8859-1");
}

===编辑===

测试:

    byte[] d = {0, 1, 2, 3, 4, (byte)128, (byte)129, (byte)130}; // some not defined values
    byte[] dd = toStringAndBack(d);
    for (byte b : dd)
        System.out.print((b&0xFF) + " ");

输出:

0 1 2 3 4 128 129 130

因此,即使没有定义的字节似乎也可以正确转换。

2 个答案:

答案 0 :(得分:1)

让我们测试一下:

// all possible bytes
byte[] bin = new byte[256];
for (int i=0; i<bin.length; i++)
    bin[i] = (byte)i;

// convert to string
String s = new String(bin, "ISO-8859-1");
for (int i=0; i<s.length(); i++)
{
    if (s.charAt(i) != i)
        System.out.println(i + " s[i]=" + s.charAt(i));
}

// convert back to byte[]
byte[] bout = s.getBytes("ISO-8859-1");
for (int i=0; i<bin.length; i++)
{
    if (bin[i] != bout[i])
        System.out.println(i + " in=" + bin[i] + " bout=" + bout[i]);
}

System.out.println("done");

仅打印done

因此,至少对于当前的ISO-8859-1实现,操作是二进制安全的,如问题中所定义。

编辑:
当前的实施是sun.nio.cs.ISO_8859_1。 查看源它只检查char是否&lt; 256,以决定是否可以编码。

答案 1 :(得分:1)

constructor you're using说:

  

当给定字节在给定字符集中无效时,此构造函数的行为未指定。

所以理论上它可能会失败,因为ISO-8859-1没有赋值给任何值,例如0-31和128-160。

这意味着即使它适用于给定JVM的String实现(或ISO-8859-1的Charset实现),也不能依赖于它在另一个JVM上String / Charset实现(无论这是来自同一供应商的JVM的不同点,还是不同供应商的JVM)。