java - 如何在 Java 中将二进制数据转换为字符串并返回?

标签 java serialization

我在一个文件中有二进制数据,我可以将其读入字节数组并毫无问题地处理。现在我需要通过网络连接将部分数据作为 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 解析器在提示。出于某种原因,当我遇到这个看似独立的问题时,我并没有意识到这是同一问题的新症状。

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

最佳答案

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();
    }
  }
}

关于java - 如何在 Java 中将二进制数据转换为字符串并返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20778/

相关文章:

java - Parcelable 在 Intent putExtra 上写入可序列化对象时遇到 IOException

Java 应用程序(处理 IDE)附加窗口在 i3wm 中不可见,常见修复不起作用

java.lang.NoClassDefFoundError : org/hibernate/cache/TimestampsRegion

java - 使用 Jackson 序列化自定义 map

java - 数据库存储与文件存储

c# - 具有 Stream 类型成员的对象的 JSON.NET 序列化?

java - ^ 运算符在 Java 中的作用是什么?

java - 为什么我们可以在类加载之前使用new运算符

Javacard 初学者 - 问题

c# - JSON.net 将 C# 对象序列化为 JSON 问题