gpt4 book ai didi

java - 读取包含无符号数字的二进制流

转载 作者:行者123 更新时间:2023-12-02 12:49:51 25 4
gpt4 key购买 nike

我想读取包含32位无符号整数和8位无符号整数的二进制文件。我已经知道DataInputStream了,但是它的方法readInt返回有符号整数,没有读取无符号int的方法(对于16位和8位整数有这种方法)。
读取单独的字节并按位将它们串联是“正式”的方法吗?将字节读入ByteArray并使用bitshift和按位or从字节组成整数会大大降低性能吗?

最佳答案

您可以使用

long value = Integer.toUnsignedLong​(dataInputStream.readInt());
这等效于Java 8之前的代码
long value = dataInputStream.readInt() & 0xFFFFFFFFL;
关键是带符号或无符号只是位模式的不同解释,但是要读取四个字节的数量, readInt()总是足够的。上面的操作将转换为带符号的 long,这是一种能够覆盖所有unsigned int值的数据类型。
但是,由于 int已经保存了所有信息,因此无需立即将其转换为 long。用来表示带符号数字的 Two’s Complement甚至允许执行基本操作,即 +-*,而无需区分带符号的数字和无符号的数字。对于其他操作,Java 8引入了通过将 int值解释为无符号来执行它们的方法:
  • Integer.divideUnsigned​(…)
  • Integer.remainderUnsigned​(…)
  • Integer.compareUnsigned​(…)
  • Integer.toUnsignedString​(…)

  • 我遇到的一个实际例子是解析类文件。这些文件在某些​​地方的大小被编码为unsigned int,但是对于大多数标准Java API,类文件以字节数组或 ByteBuffer实例的形式提供,它们不能包含超过23个字节。因此,处理一些大数字是不必要的复杂操作,因为它们无论如何还是无法纠正的,因为必须截断包含这么大规格的类文件。
    因此,处理此问题的代码基本上如下所示:
    int size = input.readInt();
    if(Integer.compareUnsigned(size, Integer.MAX_VALUE)>0) throw new IllegalArgumentException(
    "truncated class file (attribute size "+Integer.toUnsignedString(size)+')');
    // just use the int value
    或没有Java 8功能
    (甚至更简单,只要读者理解 Two’s Complement):
    int size = input.readInt();
    if(size < 0) throw new IllegalArgumentException(
    "truncated class file (attribute size "+(size&0xFFFFFFFFL)+')');
    // just use the int value
    (另请参阅 this answer)

    关于java - 读取包含无符号数字的二进制流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63138575/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com