【问题标题】:How do you convert binary data to Strings and back in Java?如何在 Java 中将二进制数据转换为字符串并返回?
【发布时间】:2010-09-06 10:52:56
【问题描述】:

我在一个文件中有二进制数据,我可以将其读入字节数组并毫无问题地处理。现在我需要通过网络连接将部分数据作为 XML 文档中的元素发送。我的问题是,当我将数据从字节数组转换为字符串并转换回字节数组时,数据已损坏。我已经在一台机器上对此进行了测试,以将问题与字符串转换隔离开来,所以我现在知道它没有被 XML 解析器或网络传输损坏。

我现在得到的是

byte[] buffer = ...; // read from file
// a few lines that prove I can process the data successfully
String element = new String(buffer);
byte[] newBuffer = element.getBytes();
// a few lines that try to process newBuffer and fail because it is not the same data anymore

有谁知道如何在不丢失数据的情况下将二进制转换为字符串并返回?

回答:谢谢山姆。我觉得自己像个白痴。我昨天回答了这个问题,因为我的 SAX 解析器在抱怨。出于某种原因,当我遇到这个看似独立的问题时,我并没有想到这是同一问题的新症状。

编辑:为了完整起见,我使用了 Apache Commons Codec 包中的 Base64 类来解决这个问题。

【问题讨论】:

    标签: java serialization


    【解决方案1】:

    String(byte[]) 将数据视为默认字符编码。因此,字节如何从 8 位值转换为 16 位 Java Unicode 字符不仅会因操作系统而异,甚至会因在同一台机器上使用不同代码页的不同用户而异!此构造函数仅适用于解码您自己的文本文件之一。不要尝试在 Java 中将任意字节转换为字符!

    编码为base64 是一个很好的解决方案。这就是通过 SMTP(电子邮件)发送文件的方式。 (免费)Apache Commons Codec 项目将完成这项工作。

    byte[] bytes = loadFile(file);          
    //all chars in encoded are guaranteed to be 7-bit ASCII
    byte[] encoded = Base64.encodeBase64(bytes);
    String printMe = new String(encoded, "US-ASCII");
    System.out.println(printMe);
    byte[] decoded = Base64.decodeBase64(encoded);
    

    或者,您可以使用 Java 6 DatatypeConverter

    import java.io.*;
    import java.nio.channels.*;
    import javax.xml.bind.DatatypeConverter;
    
    public class EncodeDecode {    
      public static void main(String[] args) throws Exception {
        File file = new File("/bin/ls");
        byte[] bytes = loadFile(file, new ByteArrayOutputStream()).toByteArray();
        String encoded = DatatypeConverter.printBase64Binary(bytes);
        System.out.println(encoded);
        byte[] decoded = DatatypeConverter.parseBase64Binary(encoded);
        // check
        for (int i = 0; i < bytes.length; i++) {
          assert bytes[i] == decoded[i];
        }
      }
    
      private static <T extends OutputStream> T loadFile(File file, T out)
                                                           throws IOException {
        FileChannel in = new FileInputStream(file).getChannel();
        try {
          assert in.size() == in.transferTo(0, in.size(), Channels.newChannel(out));
          return out;
        } finally {
          in.close();
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

      看到这个问题,How do you embed binary data in XML? 与其将 byte[] 转换为 String 然后在某处推入 XML,不如通过 BASE64 编码将 byte[] 转换为 String(某些 XML 库有一种类型可以为您执行此操作)。从 XML 中取回字符串后,BASE64 解码。

      使用http://commons.apache.org/codec/

      由于各种奇怪的字符集限制和非打印字符的存在,您的数据可能会变得混乱。带 BASE64 的棒。

      【讨论】:

        【解决方案3】:

        您是如何构建 XML 文档的?如果您使用 java 的内置 XML 类,则应为您处理字符串编码。

        看看 javax.xml 和 org.xml 包。这就是我们用来生成 XML 文档的东西,它可以很好地处理所有的字符串编码和解码。

        ---编辑:

        嗯,我想我误解了这个问题。您不是要对常规字符串进行编码,而是要对一组任意二进制数据进行编码?在这种情况下,较早评论中建议的 Base64 编码可能是可行的方法。我相信这是在 XML 中编码二进制数据的一种相当标准的方式。

        【讨论】:

          【解决方案4】:

          如果你用 base64 编码,这会将任何数据转换为 ascii 安全文本,但 base64 编码的数据比原始数据大

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-02
            • 2019-02-02
            • 1970-01-01
            • 1970-01-01
            • 2016-01-14
            • 1970-01-01
            • 2014-05-10
            • 2012-01-27
            相关资源
            最近更新 更多