Java中字节缓冲区的队列

时间:2014-11-25 14:25:11

标签: java queue bytebuffer

我想将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的第一个值之外没有其他值被添加到队列头部的情况?

1 个答案:

答案 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);
}