是否可以通过确定要读取的数量来循环读取位?

有一个 DataInputStream 从中读取

我遇到了一个特定的算法:

  1. int[] nmbrs = new int[64];

  2. 读取一个 4 位无符号整数。将读取的值分配给长度

  3. 对于 (int i = 0; i < 64; i++)

    3.1 读取一个长度位的无符号整数作为nmbrs[i]

可以用Java写吗?怎么写呢?


至尊宝的传说
浏览 95回答 2
2回答

呼如林

可以用Java写吗?怎么写呢?Java 没有提供以小于一个字节的单位执行 I/O 的机制,但您可以在面向字节的 I/O 之上实现它。您需要在读取时一次缓冲一个或多个字节,并跟踪该缓冲区内的位级位置。另请注意,这对(逻辑)位顺序问题很敏感——即您是从最高位读到最低位还是相反?

叮当猫咪

创建一个BitInputStream从底层读取位的类DataInputStream。像这样:public final class BitInputStream implements Closeable {&nbsp; &nbsp; private final InputStream in;&nbsp; &nbsp; private final ByteOrder streamBitOrder;&nbsp; &nbsp; private int bits;&nbsp; &nbsp; private byte bitsLeft;&nbsp; &nbsp; public BitInputStream(InputStream in) {&nbsp; &nbsp; &nbsp; &nbsp; this(in, ByteOrder.BIG_ENDIAN);&nbsp; &nbsp; }&nbsp; &nbsp; public BitInputStream(InputStream in, ByteOrder bitOrder) {&nbsp; &nbsp; &nbsp; &nbsp; Objects.requireNonNull(in);&nbsp; &nbsp; &nbsp; &nbsp; Objects.requireNonNull(bitOrder);&nbsp; &nbsp; &nbsp; &nbsp; this.in = in;&nbsp; &nbsp; &nbsp; &nbsp; this.streamBitOrder = bitOrder;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public void close() throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; this.in.close();&nbsp; &nbsp; }&nbsp; &nbsp; public int readBit() throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; if (this.bitsLeft == 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((this.bits = this.in.read()) == -1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new EOFException();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.bitsLeft = 8;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; int bitIdx = (this.streamBitOrder == ByteOrder.BIG_ENDIAN ? this.bitsLeft - 1 : 8 - this.bitsLeft);&nbsp; &nbsp; &nbsp; &nbsp; this.bitsLeft--;&nbsp; &nbsp; &nbsp; &nbsp; return (this.bits >> bitIdx) & 1;&nbsp; &nbsp; }&nbsp; &nbsp; public int readInt() throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; return readInt(Integer.SIZE, this.streamBitOrder);&nbsp; &nbsp; }&nbsp; &nbsp; public int readInt(ByteOrder bitOrder) throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; return readInt(Integer.SIZE, bitOrder);&nbsp; &nbsp; }&nbsp; &nbsp; public int readInt(int len) throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; return readInt(len, this.streamBitOrder);&nbsp; &nbsp; }&nbsp; &nbsp; public int readInt(int len, ByteOrder bitOrder) throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; if (len == 0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0;&nbsp; &nbsp; &nbsp; &nbsp; if (len < 0 || len > Integer.SIZE)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Invalid len: " + len + " (must be 0-" + Integer.SIZE + ")");&nbsp; &nbsp; &nbsp; &nbsp; int value = 0;&nbsp; &nbsp; &nbsp; &nbsp; if (bitOrder == ByteOrder.BIG_ENDIAN) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < len; i++)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value = (value << 1) | readBit();&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < len; i++)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value |= readBit() << i;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return value;&nbsp; &nbsp; }}测试public static void main(String[] args) throws Exception {&nbsp; &nbsp; String bitData = "0101 00001 00001 00010 00011 00101 01000 01101 10101" // 5: 1, 1, 2, 3, 5, 8, 13, 21&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + " 0011 000 001 010 011 100 101 110 111";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 3: 0, 1, 2, 3, 4, 5, 6, 7&nbsp; &nbsp; BigInteger bi = new BigInteger(bitData.replaceAll(" ", ""), 2);&nbsp; &nbsp; System.out.println("0x" + bi.toString(16) + " = 0b" + bi.toString(2));&nbsp; &nbsp; byte[] byteData = bi.toByteArray();&nbsp; &nbsp; try (BitInputStream in = new BitInputStream(new ByteArrayInputStream(byteData))) {&nbsp; &nbsp; &nbsp; &nbsp; int[] nmbrs = readNmbrs(in);&nbsp; &nbsp; &nbsp; &nbsp; int[] nmbrs2 = readNmbrs(in);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(Arrays.toString(nmbrs));&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(Arrays.toString(nmbrs2));&nbsp; &nbsp; }}private static int[] readNmbrs(BitInputStream in) throws IOException {&nbsp; &nbsp; int[] nmbrs = new int[8];&nbsp; &nbsp; int length = in.readInt(4);&nbsp; &nbsp; for (int i = 0; i < nmbrs.length; i++)&nbsp; &nbsp; &nbsp; &nbsp; nmbrs[i] = in.readInt(length);&nbsp; &nbsp; return nmbrs;}输出0x5084432a1b53053977 = 0b10100001000010001000011001010100001101101010011000001010011100101110111[1, 1, 2, 3, 5, 8, 13, 21][0, 1, 2, 3, 4, 5, 6, 7]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java