簡體   English   中英

從ByteBuffer中刪除前n個字節

[英]Remove first n bytes from a ByteBuffer

如何在不更改或降低容量的情況下從ByteBuffer中刪除前n個字節? 結果應該是第0個字節是n + 1個字節。 Java中是否有更好的數據類型可以執行此類操作?

您可以嘗試這樣的事情:

public void removeBytesFromStart(ByteBuffer bf, int n) {
    int index = 0;
    for(int i = n; i < bf.position(); i++) {
        bf.put(index++, bf.get(i));
        bf.put(i, (byte)0);
    }
    bf.position(index);
}

或類似這樣的東西:

public void removeBytesFromStart2(ByteBuffer bf, int n) {
    int index = 0;
    for(int i = n; i < bf.limit(); i++) {
        bf.put(index++, bf.get(i));
        bf.put(i, (byte)0);
    }
    bf.position(bf.position()-n);
}

這使用ByteBuffer類的絕對getput方法,並將位置設置在下一個寫入位置。

請注意,絕對put方法是可選的,這意味着擴展抽象類ByteBuffer的類可能無法為其提供實現,例如,它可能拋出ReadOnlyBufferException

是否選擇循環直到位置或直到極限取決於緩沖區的使用方式,例如,如果手動設置位置 ,則可能要使用循環直到limit 如果不這樣做,則循環直到position足夠且更有效。

這是一些測試:

@Test
public void removeBytesFromStart() {
    ByteBuffer bf = ByteBuffer.allocate(16);
    int expectedCapacity = bf.capacity();
    bf.put("abcdefg".getBytes());

    ByteBuffer expected = ByteBuffer.allocate(16);
    expected.put("defg".getBytes());

    removeBytesFromStart(bf, 3);

    Assert.assertEquals(expectedCapacity, bf.capacity());
    Assert.assertEquals(0, bf.compareTo(expected));
}

@Test
public void removeBytesFromStartInt() {
    ByteBuffer bf = ByteBuffer.allocate(16);
    int expectedCapacity = bf.capacity();
    bf.putInt(1);
    bf.putInt(2);
    bf.putInt(3);
    bf.putInt(4);

    ByteBuffer expected = ByteBuffer.allocate(16);
    expected.putInt(2);
    expected.putInt(3);
    expected.putInt(4);

    removeBytesFromStart2(bf, 4);

    Assert.assertEquals(expectedCapacity, bf.capacity());
    Assert.assertEquals(0, bf.compareTo(expected));
}

我認為您正在尋找的方法是ByteBuffer的compact()方法

即使文檔說:

“將緩沖區當前位置與其限制之間的字節(如果有的話)復制到緩沖區的開頭。也就是說,將索引p = position()處的字節復制到索引零,將索引p + 1處的字節復制為索引復制到索引1,依此類推,直到索引limit()-1處的字節復制到索引n = limit()-1-p。然后將緩沖區的位置設置為n + 1並將其限制設置為容量”。

我不確定該方法是否確實能夠做到這一點,因為在調試時,似乎該方法只是執行buffer.limit = buffer.capacity

您的意思是將所有元素移到緩沖區的開頭嗎? 像這樣:

    int n = 4;
    //allocate a buffer of capacity 10 
    ByteBuffer b = ByteBuffer.allocate(10); 

    // add data to buffer
    for (int i = 0; i < b.limit(); i++) {
        b.put((byte) i);
    }

    // print buffer
    for (int i = 0; i < b.limit(); i++) {
        System.out.print(b.get(i) + " ");
    }

    //shift left the elements from the buffer
    //add zeros to the end
    for (int i = n; i < b.limit() + n; i++) {
        if (i < b.limit()) {
            b.put(i - n, b.get(i));
        } else {
            b.put(i - n, (byte) 0);
        }
    }
    //print buffer again
    System.out.println();
    for (int i = 0; i < b.limit(); i++) {
        System.out.print(b.get(i) + " ");
    }

對於n = 4,它將打印:

0 1 2 3 4 5 6 7 8 9 
4 5 6 7 8 9 0 0 0 0

為此使用緊湊的方法。 例如:

    ByteBuffer b = ByteBuffer.allocate(32);
    b.put("hello,world".getBytes());
    b.position(6);      
    b.compact();
    System.out.println(new String(b.array()));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM