2014-11-25 64 views
0

字节的缓冲区我想要的ByteBuffers添加到Java中的队列,所以我有以下代码,for循环队列中的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); 
} 
} 

内部工作似乎正常工作为temp值设置到正确的值,然后通过调用addQueue方法将其添加到队列中。然而,只有bytebuffer的第一个字母才会被添加到queue,而没有其他的。因为当我在head的队列中的第一个值时,我得到的号码是116,但是当我尝试获得其他值时,它们是0,这是不正确的。为什么会发生这种情况,除了bytbuffer的第一个值之外没有其他值被添加到队列头部?

+0

你的内循环产生的ByteBuffers 1024,其中每个只有一个字节从'bbuf'复制。那是你要的吗?或者你打算创建一个包含原始'bbuf'的1024字节“切片”的系列缓冲区? – VGR 2014-11-26 16:39:30

+0

@VGR我想要一系列1024字节的原始片 – jgr208 2014-11-29 00:39:06

回答

1

ByteBuffer.allocate创建一个新的ByteBuffer。在内部循环的每次迭代中,您正在创建一个新的缓冲区,在其中放置一个字节,并将该缓冲区传递给addQueue。你这样做了1024次(在外循环的每次迭代中),所以你创建了1024个具有单字节集的缓冲区;在每个缓冲区中,所有其他字节将为零。

根本没有使用外循环的i循环变量。无论如何,如果你的缓冲区只有1024字节大小,我不知道你为什么要跳过10000字节。

slice方法可以用来从一个较大的创建更小的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中的任何字节也会改变其中一个分片缓冲区。这可能是你想要的,因为它比制作缓冲区副本更有效率。 (如果您的原始缓冲区很大,可能效率会更高;您是否真的需要内存中一个千兆字节缓冲区的两个副本?)

如果您确实需要将所有字节复制到独立缓冲区中,而不管发生内存使用,你可以有你的addQueue方法复制每个缓冲空间:

private void addQueue(ByteBuffer bbuf) 
{ 
    bbuf = ByteBuffer.allocate(bbuf.remaining()).put(bbuf); // copy 
    bbuf.flip(); 
    messageQueue.add(bbuf); 
}