亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

是否可以通過確定要讀取的數量來循環讀取位?

是否可以通過確定要讀取的數量來循環讀取位?

至尊寶的傳說 2022-12-15 16:00:35
有一個 DataInputStream 從中讀取我遇到了一個特定的算法:int[] nmbrs = new int[64];讀取一個 4 位無符號整數。將讀取的值分配給長度對于 (int i = 0; i < 64; i++)3.1 讀取一個長度位的無符號整數作為nmbrs[i]可以用Java寫嗎?怎么寫呢?
查看完整描述

2 回答

?
呼如林

TA貢獻1798條經驗 獲得超3個贊

可以用Java寫嗎?怎么寫呢?

Java 沒有提供以小于一個字節的單位執行 I/O 的機制,但您可以在面向字節的 I/O 之上實現它。您需要在讀取時一次緩沖一個或多個字節,并跟蹤該緩沖區內的位級位置。

另請注意,這對(邏輯)位順序問題很敏感——即您是從最高位讀到最低位還是相反?


查看完整回答
反對 回復 2022-12-15
?
叮當貓咪

TA貢獻1776條經驗 獲得超12個贊

創建一個BitInputStream從底層讀取位的類DataInputStream。


像這樣:


public final class BitInputStream implements Closeable {


    private final InputStream in;

    private final ByteOrder streamBitOrder;

    private int bits;

    private byte bitsLeft;


    public BitInputStream(InputStream in) {

        this(in, ByteOrder.BIG_ENDIAN);

    }


    public BitInputStream(InputStream in, ByteOrder bitOrder) {

        Objects.requireNonNull(in);

        Objects.requireNonNull(bitOrder);

        this.in = in;

        this.streamBitOrder = bitOrder;

    }


    @Override

    public void close() throws IOException {

        this.in.close();

    }


    public int readBit() throws IOException {

        if (this.bitsLeft == 0) {

            if ((this.bits = this.in.read()) == -1)

                throw new EOFException();

            this.bitsLeft = 8;

        }

        int bitIdx = (this.streamBitOrder == ByteOrder.BIG_ENDIAN ? this.bitsLeft - 1 : 8 - this.bitsLeft);

        this.bitsLeft--;

        return (this.bits >> bitIdx) & 1;

    }


    public int readInt() throws IOException {

        return readInt(Integer.SIZE, this.streamBitOrder);

    }


    public int readInt(ByteOrder bitOrder) throws IOException {

        return readInt(Integer.SIZE, bitOrder);

    }


    public int readInt(int len) throws IOException {

        return readInt(len, this.streamBitOrder);

    }


    public int readInt(int len, ByteOrder bitOrder) throws IOException {

        if (len == 0)

            return 0;

        if (len < 0 || len > Integer.SIZE)

            throw new IllegalArgumentException("Invalid len: " + len + " (must be 0-" + Integer.SIZE + ")");

        int value = 0;

        if (bitOrder == ByteOrder.BIG_ENDIAN) {

            for (int i = 0; i < len; i++)

                value = (value << 1) | readBit();

        } else {

            for (int i = 0; i < len; i++)

                value |= readBit() << i;

        }

        return value;

    }


}

測試


public static void main(String[] args) throws Exception {

    String bitData = "0101 00001 00001 00010 00011 00101 01000 01101 10101" // 5: 1, 1, 2, 3, 5, 8, 13, 21

                  + " 0011 000 001 010 011 100 101 110 111";                // 3: 0, 1, 2, 3, 4, 5, 6, 7

    BigInteger bi = new BigInteger(bitData.replaceAll(" ", ""), 2);

    System.out.println("0x" + bi.toString(16) + " = 0b" + bi.toString(2));

    byte[] byteData = bi.toByteArray();

    try (BitInputStream in = new BitInputStream(new ByteArrayInputStream(byteData))) {

        int[] nmbrs = readNmbrs(in);

        int[] nmbrs2 = readNmbrs(in);

        System.out.println(Arrays.toString(nmbrs));

        System.out.println(Arrays.toString(nmbrs2));

    }

}

private static int[] readNmbrs(BitInputStream in) throws IOException {

    int[] nmbrs = new int[8];

    int length = in.readInt(4);

    for (int i = 0; i < nmbrs.length; i++)

        nmbrs[i] = in.readInt(length);

    return nmbrs;

}

輸出


0x5084432a1b53053977 = 0b10100001000010001000011001010100001101101010011000001010011100101110111

[1, 1, 2, 3, 5, 8, 13, 21]

[0, 1, 2, 3, 4, 5, 6, 7]


查看完整回答
反對 回復 2022-12-15
  • 2 回答
  • 0 關注
  • 122 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號