【问题标题】:Why does bytes data change during conversion between bytes and strings?为什么字节和字符串之间的转换过程中字节数据会发生变化?
【发布时间】:2020-11-11 03:54:09
【问题描述】:

我发现了一个我在 Java 中无法真正理解的现象,我发布了一个问题

  1. 将一些数据放入字节数组中
  2. 将字节数组转换为字符串
  3. 将转换后的字符串转换回字节数组
  4. 比较第一个数据和转换后的数据时,有些会输出不同。

源码和日志如下

源代码

// 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

即使在转换后,我也希望保留与现有数据相同的数据 有解决办法吗?

【问题讨论】:

  • 这能回答你的问题吗? Java byte array contains negative numbers
  • 很好的问题,很容易混淆。 Java 没有无符号字节(负数)。如果您想保留负数,则可以使用其他数据类型,例如 int 数组 int[] beforeInt = new int[]{-83, -95, -55, -49, 3};,或者您可以将它们转换回无符号字节,如下所示:stackoverflow.com/a/6966609/1270000
  • 63 是?,当字节组合没有映射到字符集中的有效字符时用作替换字符(并且字符集不是 UTF-8,它将使用不同的字符作为替换字符)。因此,问题取决于您的实际字符集(打印出System.getProperty("file.encoding"))。您应该始终明确指定字符集。但是,如果您的目标是将 二进制 数据存储在字符串中,那么这不是正确的方法(尽管您可以使用字符集 iso-8859-1)。

标签: java string byte


【解决方案1】:

您应该像这样使用编码器和解码器:

        // 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 之类的 charSet,并且构造函数可以添加或修改一些数据。使用 Base64 编码器和解码器要好得多。 亲切的问候。

【讨论】:

    猜你喜欢
    • 2011-10-31
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多