我正在尝试将字节数组转换为String,然后返回字节数组。第一部分(byte [] to string)工作,当我尝试将字符串转换回字节数组然后比较我得到的初始字节数组时,我发现它们是不同的。我猜这是一个编码问题,我尝试了不同的解决方案(使用UTF-8,ISO-8859-1,UTF-16LE等),但似乎都没有。
有谁知道如何解决这个问题? 提前致谢
[66, 77, -10, -44, 1, 0, 0, 0, 0, 0, 1, -1, ....... ,-1]
false
这是输出:(结果太长了,所以我剪了一部分)
var suggestionss = getSuggestions(search_text, urll);
答案 0 :(得分:3)
Arrays.toString(byte[])
并不只是将byte []转换为String,而是将其转换为人类可读的格式。然后在该字符串上调用getBytes()
时,它将表示原始字节信息的字符转换为byte [],以及格式字符,例如括号和逗号。
如果要从byte []创建String,请使用String构造函数,该构造函数使用byte []显式创建包含数据的String对象:
...
//byte[] to string
String byte_string = new String(byte_array);
//String to byte[]
byte[] string_byte = byte_string.getBytes();
System.out.println(Arrays.equals(byte_array, string_byte));
正如其他人所指出的,并非所有二进制数据都在所有字符集中都清晰地表示,因此您可以通过显式指定编码来使转换工作。
例如,当我尝试编码可执行程序文件(.exe)时,上面的示例代码仍然输出false
,但如果我指定ISO_8859_1编码,则比较为true
:
//byte[] to string
String byte_string = new String(byte_array, StandardCharsets.ISO_8859_1);
//String to byte[]
byte[] string_byte = byte_string.getBytes(StandardCharsets.ISO_8859_1);
System.out.println(Arrays.equals(byte_array, string_byte));
将数据转换为String并返回的绝对最安全的方法是使用this answer建议的base64编码:
//file to byte[]
byte[] byte_array = Files.readAllBytes(path);
byte[] encoded = Base64.encodeBase64(byte_array);
//byte[] to string
String byte_string = new String(encoded, StandardCharsets.US_ASCII);
//String to byte[]
byte[] string_byte = byte_string.getBytes(StandardCharsets.US_ASCII);
byte[] decoded = Base64.decodeBase64(string_byte);
System.out.println(Arrays.equals(byte_array, decoded));
答案 1 :(得分:1)
Char / String包含设计的Unicode文本(与其他语言相对)。 这意味着他们
byte[]
); 所以:
byte[] b = s.getBytes(StandardCharsets.UTF_8);
s = new String(b, StandardCharsets.UTF_8);
如果没有charset参数,则使用默认编码,与平台相关。 转换可能会将占位符替换为不可表示的字符,或者二进制数据可能完全格式错误。
Text(String / char)与二进制数据(byte)完全分开。同样不是char
是2字节UTF-16BE,而byte
是1字节。