2014-11-25 101 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); 
}