Java 从 ByteBuffer 中删除前 n 个字节
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18031927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Remove first n bytes from a ByteBuffer
提问by Blaker
How can I remove the first nnumber of bytes from a ByteBuffer without changing or lowering the capacity? The result should be that the 0th byte is the n+1byte. Is there a better data type in Java to do this type of action?
如何在不更改或降低容量的情况下从 ByteBuffer 中删除前n个字节?结果应该是第0个字节是n+1个字节。Java 中是否有更好的数据类型来执行此类操作?
采纳答案by A4L
You could try something like this:
你可以尝试这样的事情:
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);
}
Or something like this:
或者像这样:
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);
}
This uses the absolute getand putmethod of the ByteBufferclass and sets the positionat next write position.
本品采用绝对GET和看跌期权的方法的ByteBuffer类和设置位置在下次写位置。
Note that the absolute put
method is optional, which means that a class that extends the abstract class ByteBuffer
may not provide an implementation for it, for example it might throw a ReadOnlyBufferException
.
请注意,absoluteput
方法是可选的,这意味着扩展抽象类的类ByteBuffer
可能不会为其提供实现,例如它可能会抛出ReadOnlyBufferException
.
Whether you choose to loop till positionor till limitdepends on how you use the buffer, for example if you manually set the positionyou might want to use loop till limit
. If you do not then looping till position
is enough and more efficient.
无论您选择循环直到位置或至极限取决于你如何使用缓冲,例如,如果您手动设置的位置,你可能要使用循环至limit
。如果你不这样做,那么循环直到position
就足够了,而且效率更高。
Here is some testings:
以下是一些测试:
@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));
}
回答by andreih
Do you mean to shift all the element to the begining of the buffer? Like this:
您的意思是将所有元素移到缓冲区的开头吗?像这样:
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) + " ");
}
For n=4 it will print:
对于 n=4,它将打印:
0 1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 0 0 0 0
回答by PeterErnsthaft
I think the method you are looking for is the ByteBuffer's compact() method
我认为您正在寻找的方法是ByteBuffer 的 compact() 方法
Even though the documentation says:
即使文档说:
"The bytes between the buffer's current position and its limit, if any, are copied to the beginning of the buffer. That is, the byte at index p = position() is copied to index zero, the byte at index p + 1 is copied to index one, and so forth until the byte at index limit() - 1 is copied to index n = limit() - 1 - p. The buffer's position is then set to n+1 and its limit is set to its capacity."
“缓冲区当前位置与其限制之间的字节(如果有)被复制到缓冲区的开头。也就是说,索引 p = position() 处的字节被复制到索引 0,索引 p + 1 处的字节是复制到索引 1,依此类推,直到索引 limit() - 1 处的字节被复制到索引 n = limit() - 1 - p。然后将缓冲区的位置设置为 n+1,并将其限制设置为其容量.”
I am not sure that this method realy does that, because when I debug it seems like the method just does buffer.limit = buffer.capacity
.
我不确定这个方法真的能做到这一点,因为当我调试时,该方法似乎就是这样做的buffer.limit = buffer.capacity
。
回答by Serhiy Brytskyy
Use compact method for that. E.g.:
为此使用紧凑方法。例如:
ByteBuffer b = ByteBuffer.allocate(32);
b.put("hello,world".getBytes());
b.position(6);
b.compact();
System.out.println(new String(b.array()));