我想将ByteBuffers添加到java中的队列中,所以我有以下代码,
public class foo{
private Queue <ByteBuffer> messageQueue = new LinkedList<ByteBuffer>();
protected boolean queueInit(ByteBuffer bbuf)
{
if(bbuf.capacity() > 10000)
{
int limit = bbuf.limit();
bbuf.position(0);
for(int i = 0;i<limit;i=i+10000)
{
int kb = 1024;
for(int j = 0;j<kb;j++)
{
ByteBuffer temp = ByteBuffer.allocate(kb);
temp.array()[j] = bbuf.get(j);
System.out.println(temp.get(j));
addQueue(temp);
}
}
}
System.out.println(messageQueue.peek().get(1));
return true;
}
private void addQueue(ByteBuffer bbuf)
{
messageQueue.add(bbuf);
}
}
for循环的内部工作似乎正常工作,因为temp
值设置为正确的值,然后应通过调用addQueue
方法将其添加到队列中。但是,只有bytebuffer
的第一个字母才会添加到queue
而没有其他内容。因为当我peek
位于队列的head
中的第一个值时,我得到的数字116
就像我应该的那样,但当我尝试在头部获得其他值时,它们是{{ 1}}这是不正确的。为什么可能会发生除了bytbuffer的第一个值之外没有其他值被添加到队列头部的情况?
答案 0 :(得分:1)
ByteBuffer.allocate
创建一个新的ByteBuffer。在内部j
循环的每次迭代中,您将创建一个新缓冲区,在其中放置一个字节,并将该缓冲区传递给addQueue
。你这样做了1024次(在外循环的每次迭代中),所以你要创建1024个缓冲区,它们有一个字节集;在每个缓冲区中,所有其他字节将为零。
您根本没有使用外部循环的i
循环变量。如果你的缓冲区大小只有1024字节,我不知道你为什么要跳过超过10000字节。
slice方法可用于从较大的ByteBuffers中创建较小的ByteBuffers:
int kb = 1024;
while (bbuf.remaining() >= kb) {
ByteBuffer temp = bbuf.slice();
temp.limit(1024);
addQueue(temp);
bbuf.position(bbuf.position() + kb);
}
if (bbuf.hasRemaining()) {
ByteBuffer temp = bbuf.slice();
addQueue(temp);
}
记住新的ByteBuffers将与bbuf
共享内容非常重要。意思是,对bbuf
中的任何字节进行更改也会改变其中一个切片缓冲区。这可能是你想要的,因为它比制作缓冲区的副本更有效。 (如果你的原始缓冲区很大,可能会更有效率;你真的想要在内存中存储一个1 GB缓冲区的副本吗?)
如果您确实需要将所有字节复制到独立缓冲区中,无论是否产生内存使用情况,您都可以使用addQueue
方法复制每个缓冲区空间:
private void addQueue(ByteBuffer bbuf)
{
bbuf = ByteBuffer.allocate(bbuf.remaining()).put(bbuf); // copy
bbuf.flip();
messageQueue.add(bbuf);
}