【问题标题】:String constructor differences between operating systems操作系统之间的字符串构造函数差异
【发布时间】:2013-07-16 04:50:59
【问题描述】:

我有以下代码:

byte[] b = new byte[len]; //len is preset to 157004 in this example
//fill b with data by reading from a socket
String pkt = new String(b);
System.out.println(b.length + " " + pkt.length());

这会在 Ubuntu 上打印出两个不同的值; 157004 和 147549,但在 OS X 上的值相同。这个字符串实际上是 ImageIO 库正在传输的图像。因此,在 OS X 上我可以将字符串解码成图像就好了,但在 Ubuntu 上我不能。

我在 OS X 上使用版本 1.6.0_45,并在 Ubuntu 上尝试了相同的版本,除了 Oracle jdk 7 和默认的 openjdk。

我注意到我可以通过使用 Latin-1 解码来使字符串长度等于字节数组长度:

String pkt = new String(b,"ISO-8859-1");

但是这并不能解码图像,并且理解发生了什么可能很困难,因为字符串对我来说看起来像垃圾。

我很困惑,因为我使用的是相同的 jdk 版本,但操作系统不同。

【问题讨论】:

标签: character-encoding java


【解决方案1】:

这个字符串实际上是ImageIO库正在传输的图像。

这就是你的错误所在。

图像不是文本数据——它是二进制数据。如果确实需要将其编码为字符串,则应使用 base64。我个人喜欢public domain base64 encoder/decoder at iharder.net

这不仅适用于图像 - 所有 二进制数据也适用数据等。永远不要将其视为只是编码文本 - 这是灾难的根源。

【讨论】:

  • 所以当我写它时,我使用 ImageIO.write(ByteArrayOutputStream),然后将它写入一个 ByteBuffer。所以我只需要在base64中解码,对吗?
  • @codersarepeople:不,您可以直接将byte[] 转换为带有base64 的字符串...这就是编码。然后,当字符串在另一侧恢复时,您将再次将其从 base64 解码byte[],然后将其包装在 ByteArrayInputStream 中。
【解决方案2】:

Ubuntu 默认使用 utf-8,这是一种可变长度编码,因此字符串和字节数据的长度不同。这是差异的根源,但对于解决方案,我遵从 Jon 的回答。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 1970-01-01
    • 2023-03-15
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    相关资源
    最近更新 更多