如何将负字节值转换为短整数或整数?

How to convert negative byte value to either short or integer?

我们有一个文件,其中包含特定格式的字节数组,如 header,然后是数据。此文件由另一个 java 程序生成,然后我们通过另一个 java 程序以与写入文件相同的格式读取同一个文件。

生成该文件的程序将 lengthOfKey 填充为字节,这是正确的,因为这正是我们需要的,如下所示。

    for (Map.Entry<byte[], byte[]> entry : holder.entrySet()) {
        byte typeKey = 0;

        // getting the key length as byte (that's what we need to do)
        byte lengthOfKey = (byte) entry.getKey().length;
        byte[] actualKey = entry.getKey();
    }

现在 byte 只能将最大值存储为 127,我们在读取文件时看到一些记录 lengthOfKey 变为负值,如下所示:

正在读取文件的程序:

byte keyType = dis.readByte();

// for some record this is coming as negative. For example -74
byte lengthOfKey = dis.readByte();

现在我的问题是: 有什么方法可以找出密钥的实际长度,因为它在写入时被转换为 -74 .我的意思是它应该大于 127,这就是它被转换为 -74 的原因,但实际值是多少?

我认为问题是如何将负字节值转换为短整数或整数?我只是想验证一下密钥的实际长度是多少,因为它被转换为负值。

如果 entry.getKey().length 的原始长度大于 255,则实际长度信息将丢失。但是,如果原始长度在128255之间,则可以检索。

转换为 byte 的缩小转换仅保留最低有效 8 位,但第 8 位现在被解释为 -128 而不是 128

您可以使用 0xFF 执行位与运算,这将保留所有位,但会隐式地将值加宽回 int

int length = lengthOfKey & 0xFF;

lengthOfKey (byte = -74): 10110110

将其扩展为 int,符号扩展为:

lengthOfKey (int = -74): 11111111 11111111 11111111 10110110

将最后 8 位屏蔽为 int:

length (int = 182): 00000000 00000000 00000000 10110110

这会将负数 byte 转换回 128255 之间的数字。

将假定的无符号字节转换为 int。

int value = (byteValue >= (byte) 0) ? (int) byteValue : 256 + (int) byteValue; 

如果你使用Guava, it provides a number of unsigned math utilities, including UnsignedBytes.

UnsignedBytes.toInt(lengthOfKey);

请注意,他们对 toInt() 的实施正是 @rgettman 所建议的。