Java 字符串到字节[]的转换问题
我试图将字节数组转换为字符串,然后再转换回字节数组。第一部分(byte[]到string)起作用,当我尝试将字符串转换回字节数组,然后将得到的结果与初始字节数组进行比较时,我发现它们是不同的。我猜这是一个编码问题,我尝试了不同的解决方案(使用UTF-8、ISO-8859-1、UTF-16LE和其他),但似乎都不起作用 有人知道如何解决这个问题吗? 提前谢谢Java 字符串到字节[]的转换问题,java,arrays,string,byte,Java,Arrays,String,Byte,我试图将字节数组转换为字符串,然后再转换回字节数组。第一部分(byte[]到string)起作用,当我尝试将字符串转换回字节数组,然后将得到的结果与初始字节数组进行比较时,我发现它们是不同的。我猜这是一个编码问题,我尝试了不同的解决方案(使用UTF-8、ISO-8859-1、UTF-16LE和其他),但似乎都不起作用 有人知道如何解决这个问题吗? 提前谢谢 Path path = Paths.get("C:\\folder1", "profil1.bmp"); try {
Path path = Paths.get("C:\\folder1", "profil1.bmp");
try {
//file to byte[]
byte[] byte_array = Files.readAllBytes(path);
System.out.println(Arrays.toString(byte_array ));
//byte[] to string
String byte_string = Arrays.toString(byte_array);
//String to byte[]
byte[] string_byte = byte_string.getBytes();
System.out.println(Arrays.equals(byte_array, string_byte));
} catch (IOException e) {
System.out.println(e);
}
这是输出:(结果太长了,所以我把它的一部分切了下来)
Arrays.toString(byte[])
不仅将byte[]转换为字符串,还将其转换为人类可读的格式。然后在该字符串上调用getBytes()
时,它将表示原始字节信息的字符与格式字符(如括号和逗号)一起转换为字节[]
如果要从字节[]创建字符串,请使用字符串构造函数,该构造函数使用字节[]显式创建包含数据的字符串对象:
...
//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));
将数据转换为字符串并返回最安全的方法是使用base64编码,如下所示:
Arrays.toString(byte[])
不仅将byte[]转换为字符串,还将其转换为人类可读的格式。然后在该字符串上调用getBytes()
时,它将表示原始字节信息的字符与格式字符(如括号和逗号)一起转换为字节[]
如果要从字节[]创建字符串,请使用字符串构造函数,该构造函数使用字节[]显式创建包含数据的字符串对象:
...
//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));
将数据转换为字符串并返回最安全的方法是使用base64编码,如下所示:
Char/String按设计包含Unicode文本(与其他语言相反)。 这意味着他们
- 始终使用(字节的)编码前后转换为二进制数据(
)李>byte[]
- 如果字节格式不正确,则无法保存任何二进制数据
- 可能会混合使用几种文字拉丁语/西里尔语/阿拉伯语/符号
文本(字符串/字符)与二进制数据(字节)完全分离。也不是说
char
是2字节的UTF-16BE,而byte
是1字节。char/String通过设计包含Unicode文本(与其他语言相反)。
这意味着他们
- 始终使用(字节的)编码前后转换为二进制数据(
)李>byte[]
- 如果字节格式不正确,则无法保存任何二进制数据
- 可能会混合使用几种文字拉丁语/西里尔语/阿拉伯语/符号
文本(字符串/字符)与二进制数据(字节)完全分离。也不是说
char
是2个字节的UTF-16BE,而byte
是1个字节。为什么要将BMP数据视为String
?我想将其与其他信息(都是字符串)一起发送到ArrayList中,显然这两个字节[]
中的数据是不同的。尝试big-endian或little-endian(取决于您的操作系统)尝试US-ASCII
编码(但请确保在编码和解码时都使用它)。将原始数据视为字符串通常是个坏主意,但如果您别无选择…为什么要将BMP数据视为字符串
?我想将其与其他信息(都是字符串)一起发送到ArrayList中,显然这两个字节[]
中的数据是不同的。尝试big-endian或little-endian(取决于您的操作系统)尝试US-ASCII
编码(但请确保在编码和解码时都使用它)。一般来说,将原始数据视为字符串是个坏主意,但如果您别无选择……我尝试过,但仍然得到“false”。我还尝试指定要使用的编码(使用Joop Eggen的答案),但也不起作用。@HusaynHakeem我已经更新了我的答案(希望)解决了这个问题。我尝试了,但仍然得到“false”。我还尝试指定要使用的编码(使用Joop Eggen的答案),但也不起作用。@HusaynHakeem我已经更新了我的答案,希望能解决这个问题。谢谢你的解释,我现在明白我的错误了。我更改了代码并尝试按照您所说的做,但我仍然得到“false”(因此两个字符串仍然不同)感谢您的解释,我现在理解了我的错误。我更改了代码并尝试按您所说的做,但仍然得到“false”(因此这两个字符串仍然不同)
byte[] b = s.getBytes(StandardCharsets.UTF_8);
s = new String(b, StandardCharsets.UTF_8);