Base64编码/解码问题:解码后的字符串是'?'

时间:2011-06-26 13:52:21

标签: java base64 java-io

我正在尝试读取图像并使用Base64编码将其转换为字节数组,然后转换为字符串以通过网络发送。问题是,当我尝试解码Base64编码的字符串时,我收到的数据不正确。

例如。我面临着以下特殊问题的问题。

我正在使用以下代码进行编码:

byte[] b = Base64.encodeBase64(IOUtils.toByteArray(loInputStream));
String ab = new String(b);

IOUtilsorg.apache.commons.io.IOUtils

和loInput

解码代码:

byte[] c = Base64.decodeBase64(ab.getBytes());
String ca = new String(c);
System.out.println(ca);

它为已解码的String打印?

任何人都可以让我知道这个问题。

2 个答案:

答案 0 :(得分:4)

如果您的输入是图像,则将其编码为base64是有意义的 - base64是文本,并且可以用String表示。

然后再解码它,你会得到原始图像。图像通常是二进制格式;尝试将其转换为字符串是没有意义的 - 它不是文本。

即最后两行:

   String ca = new String(c);
   System.out.println(ca);

完全没有意义。

如果要检查解码是否与原始输入产生相同的输出,请执行以下操作:

  System.out.println("Original and decoded are the same: " + Arrays.equals(b,c));

(或者将字节数组保存到文件中并在图像查看器中查看图像)

答案 1 :(得分:2)

正如我所说elsewhere,在Java中,String用于文本,byte[]用于二进制数据。

字符串≠byte []

文字≠二进制数据

图像是二进制数据。 Base64是一种编码,允许通过US_ASCII兼容的文本通道传输二进制数据(对于ASCII文本的超集有类似的编码:Quoted Printable)。

所以,它就像:

Image (binary data) → Image (text, Base64 encoded binary data) → Image (binary data)

您可以使用String encodeBase64String(byte[])进行编码,使用byte[] decode(String)进行解码。这些是Base64唯一合理的API,byte[] encodeBase64(byte[])具有误导性,结果是与US_ASCII兼容的文本(因此,String不是 byte[])。< / p>

现在,text有一个charset和一个编码,String在内部使用固定的Unicode / UTF-16字符集/编码组合,你必须在从/转换为{{{}时指定一个字符集/编码1}},显式地或隐式地,使用平台的默认编码(这是String所做的)。 Base64文本是纯US_ASCII,因此您需要使用它或US_ASCII的超集。 PrintStream.println()使用UTF8,它是US_ASCII的超集,所以一切都很好。 (OTOH,内部org.apache.commons.codec.binary.Base64使用平台的默认编码,所以我想如果你使用UTF-16编码启动你的JVM会破坏。

回到主题:你试图将解码后的图像(二进制数据)打印为文本,这显然没有用。 java.util.prefs.Base64write()种方法可以编写二进制数据,因此您可以使用这些方法,并且您将获得与编写原始图像时相同的垃圾。最好使用FileOutputStream,并将生成的文件与原始图像文件进行比较。