为什么在字节和字符串之间的转换过程中字节数据会发生变化?
Why does bytes data change during conversion between bytes and strings?
我在 Java 中发现了一个我无法真正理解的现象,我 post 提出了一个问题
- 将一些数据放入字节数组
- 将字节数组转换为字符串
- 将转换后的字符串转回字节数组
- 比较第一个数据和转换后的数据时,有些数据会输出不同。
源码和日志如下
源代码
// 1. Input byte array data
byte[] beforeBytes = new byte[]{(byte)-83, (byte)-95, (byte)-55, (byte)-49, (byte)3};
log.info("Before ByteTest");
log.info("bytesLength : " + beforeBytes.length);
for (int i = 0; i < beforeBytes.length; ++i)
{
log.info(i + " : " + (int)beforeBytes[i]);
}
// 2. Convert byte array to string
String testString = new String(beforeBytes);
// 3. Convert string to byte array
byte[] afterBytes = testString.getBytes();
log.info("After ByteTest");
log.info("bytesLength : " + afterBytes.length);
for (int i = 0; i < afterBytes.length; ++i)
{
log.info(i + " : " + (int)afterBytes[i]);
}
日志
Before ByteTest
bytesLength : 5
0 : -83
1 : -95
2 : -55
3 : -49
4 : 3
After ByteTest
bytesLength : 5
0 : 63
1 : -95
2 : -55
3 : 63
4 : 3
即使在转换后我也想保留与现有数据相同的数据
有解决方法吗?
你应该使用这样的编码器和解码器:
// 2. Convert byte array to string
String testString = Base64.getEncoder().encodeToString(beforeBytes);
// 3. Convert string to byte array
byte[] afterBytes = Base64.getDecoder().decode(testString);
最后你的代码将是这样的:
// 1. Input byte array data
byte[] beforeBytes = new byte[]{(byte)-83, (byte)-95, (byte)-55, (byte)-49,
(byte)3};
log.info("Before ByteTest");
log.info("bytesLength : " + beforeBytes.length);
for (int i = 0; i < beforeBytes.length; ++i)
{
log.info(i + " : " + (byte)beforeBytes[i]);
}
// 2. Convert byte array to string
String testString = Base64.getEncoder().encodeToString(beforeBytes);
// 3. Convert string to byte array
byte[] afterBytes = Base64.getDecoder().decode(testString);
log.info("After ByteTest");
log.info("bytesLength : " + afterBytes.length);
for (int i = 0; i < afterBytes.length; ++i)
{
log.info(i + " : " + (byte)afterBytes[i]);
}
您使用的方法 .getBytes() 不是最合适的,因为您没有在构造函数中编写像 UTF-8 这样的字符集,并且构造函数可以添加或修改一些数据。使用 Base64 编码器和解码器要好得多。
亲切的问候。
我在 Java 中发现了一个我无法真正理解的现象,我 post 提出了一个问题
- 将一些数据放入字节数组
- 将字节数组转换为字符串
- 将转换后的字符串转回字节数组
- 比较第一个数据和转换后的数据时,有些数据会输出不同。
源码和日志如下
源代码
// 1. Input byte array data
byte[] beforeBytes = new byte[]{(byte)-83, (byte)-95, (byte)-55, (byte)-49, (byte)3};
log.info("Before ByteTest");
log.info("bytesLength : " + beforeBytes.length);
for (int i = 0; i < beforeBytes.length; ++i)
{
log.info(i + " : " + (int)beforeBytes[i]);
}
// 2. Convert byte array to string
String testString = new String(beforeBytes);
// 3. Convert string to byte array
byte[] afterBytes = testString.getBytes();
log.info("After ByteTest");
log.info("bytesLength : " + afterBytes.length);
for (int i = 0; i < afterBytes.length; ++i)
{
log.info(i + " : " + (int)afterBytes[i]);
}
日志
Before ByteTest
bytesLength : 5
0 : -83
1 : -95
2 : -55
3 : -49
4 : 3
After ByteTest
bytesLength : 5
0 : 63
1 : -95
2 : -55
3 : 63
4 : 3
即使在转换后我也想保留与现有数据相同的数据 有解决方法吗?
你应该使用这样的编码器和解码器:
// 2. Convert byte array to string
String testString = Base64.getEncoder().encodeToString(beforeBytes);
// 3. Convert string to byte array
byte[] afterBytes = Base64.getDecoder().decode(testString);
最后你的代码将是这样的:
// 1. Input byte array data
byte[] beforeBytes = new byte[]{(byte)-83, (byte)-95, (byte)-55, (byte)-49,
(byte)3};
log.info("Before ByteTest");
log.info("bytesLength : " + beforeBytes.length);
for (int i = 0; i < beforeBytes.length; ++i)
{
log.info(i + " : " + (byte)beforeBytes[i]);
}
// 2. Convert byte array to string
String testString = Base64.getEncoder().encodeToString(beforeBytes);
// 3. Convert string to byte array
byte[] afterBytes = Base64.getDecoder().decode(testString);
log.info("After ByteTest");
log.info("bytesLength : " + afterBytes.length);
for (int i = 0; i < afterBytes.length; ++i)
{
log.info(i + " : " + (byte)afterBytes[i]);
}
您使用的方法 .getBytes() 不是最合适的,因为您没有在构造函数中编写像 UTF-8 这样的字符集,并且构造函数可以添加或修改一些数据。使用 Base64 编码器和解码器要好得多。 亲切的问候。