将带有二进制数据的 byte[] 转换为 String

Convert byte[] with binary data to String

我有二进制格式的数据 (hex: 80 3b c8 87 0a 89),我需要将其转换为字符串,以便通过 Jackcess 将二进制数据保存在 MS Access 数据库中。我知道,我不应该将 Java 中的 String 用于二进制数据,但是 Access db 是第三方产品,我无法控制。

于是尝试将二进制数据转换并保存,可惜结果出乎意料。

byte[] byteArray = new byte[] {0x80, 0x3b, 0xc8, 0x87, 0x0a 0x89};
System.out.println(String.format("%02X ",byteArray[0])+String.format("%02X ", byteArray[1]));//gives me the same values

String value = new String(byteArray, "UTF-8");//or any other encoding
System.out.println(value);//completely different values

我想知道 new String 下发生了什么,是否有办法将二进制数据转换为字符串并具有相同的十六进制值。

注1:最初我读的是二进制文件,与十六进制无关。我使用十六进制只是为了比较数据集。

注 2有人建议使用 Base64 又名 MIME、UTF-7 等。据我了解,它采用二进制数据并将其编码为 ANSI 字符集,基本上是调整初始数据。但是,对我来说这不是解决方案,因为我必须将保存在二进制数组中的确切数据写入。

byte[] byteArray = new byte[]{0x2f, 0x7a, 0x2d, 0x28};
byte[]   bytesEncoded = Base64.encodeBase64(byteArray);
System.out.println("encoded value is " + new String(bytesEncoded ));//new data

为了安全地将任意二进制数据转换为文本,您应该使用十六进制或 base64 之类的东西。 UTF-8 等编码旨在将任意 text 数据编码为字节,而不是将任意 binary 数据编码为文本。这是源数据的区别。

我强烈建议为此使用库。例如,Guava:

String hex = BaseEncoding.base16().encode(byteArray);
// Store hex in the database in the text field...
...
// Get hex from the database from the text field...
byte[] binary = BaseEncoding.base16().decode(hex);

(当然也可以使用其他库,比如Apache Commons Codec。)

或者,将您的二进制数据保存到 Access 中为二进制数据设计的字段中,而不是将其完全转换为文本。

要吸取的基本教训 - 永远不要将二进制数据与等效字符串混淆。

我的错误是,我将初始数据从 Access 导出到 csv,同时将索引字段的类型从二进制更改为字符串(一团糟,现在我知道了)。我的解决方案是我自己的 Access 导出工具,其中所有数据都以二进制形式保存。感谢@gord-thompson - 他的评论导致了解决方案。