将带有二进制数据的 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 - 他的评论导致了解决方案。
我有二进制格式的数据 (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 - 他的评论导致了解决方案。