2009-02-20 114 views
5

将ByteBuffer bbuf_src放入另一个ByteBuffer bbuf_dest(以及知道传输多少字节)的尽可能多的字节的最有效方法是什么?我试图bbuf_dest.put(bbuf_src),但它似乎想要抛出一个BufferOverflowException,我现在无法从Sun获得javadoc(网络问题),当我需要它们时。 > :(哎呀将字节从一个字节缓冲区传输到另一个字节缓冲区


编辑:darnit,@理查德的方法(从bbuf_src支持数组使用的put())不会,如果bbuf_src是只读缓冲区工作,因为你不能访问该数组。我能在这种情况下???

+0

我想你应该把它分成两个问题。 – GEOCHET 2009-02-20 16:15:46

+0

另一半已经在这里搬迁:http://stackoverflow.com/questions/570218/downloading-sun-javadocs-mirror-websites – 2009-02-20 16:26:55

回答

1

OK,我已经适应@理查德的回答是:

public static int transferAsMuchAsPossible(
        ByteBuffer bbuf_dest, ByteBuffer bbuf_src) 
{ 
    int nTransfer = Math.min(bbuf_dest.remaining(), bbuf_src.remaining()); 
    if (nTransfer > 0) 
    { 
    bbuf_dest.put(bbuf_src.array(), 
        bbuf_src.arrayOffset()+bbuf_src.position(), 
        nTransfer); 
    bbuf_src.position(bbuf_src.position()+nTransfer); 
    } 
    return nTransfer; 
} 

和测试,以确保它的工作原理:

public static boolean transferTest() 
{ 
    ByteBuffer bb1 = ByteBuffer.allocate(256); 
    ByteBuffer bb2 = ByteBuffer.allocate(50); 
    for (int i = 0; i < 100; ++i) 
    { 
     bb1.put((byte)i); 
    } 
    bb1.flip(); 
    bb1.position(5); 
    ByteBuffer bb1a = bb1.slice(); 
    bb1a.position(2); 
    // bb3 includes the 5-100 range 
    bb2.put((byte)77); 
    // something to see this works when bb2 isn't empty 
    int n = transferAsMuchAsPossible(bb2, bb1a); 
    boolean itWorked = (n == 49); 

    if (bb1a.position() != 51) 
     itWorked = false; 
    if (bb2.position() != 50) 
     itWorked = false; 
    bb2.rewind(); 
    if (bb2.get() != 77) 
     itWorked = false; 
    for (int i = 0; i < 49; ++i) 
    { 
     if (bb2.get() != i+7) 
     { 
      itWorked = false; 
      break; 
     } 
    } 
    return itWorked; 
} 
1

你得到的BufferOverflowException因为你bbuf_dest不够大。

您将需要使用bbuf_dest.remaining()来找出的最大数量您可以从bbuf_src传送的字节:

int maxTransfer = Math.min(bbuf_dest.remaining(), bbuf_src.remaining()); 
bbuf_dest.put(bbuf_src.array(), 0, maxTransfer); 
+0

啊。这很有帮助。我想我现在知道该怎么做。谢谢。但请注意,如果bbuf_src是另一个缓冲区的视图缓冲区,则您的答案将不起作用。我想我可以适应它。 – 2009-02-20 16:39:15

8

正如你已经发现,得到了支持数组并不总是工作(只读缓冲区,直接缓冲区和内存映射文件缓冲区失败)。更好的选择是复制你的源缓冲区,并设置一个新的限制你想要传输的数据量:

int maxTransfer = Math.min(bbuf_dest.remaining(), bbuf_src.remaining()); 
// use a duplicated buffer so we don't disrupt the limit of the original buffer 
ByteBuffer bbuf_tmp = bbuf_src.duplicate(); 
bbuf_tmp.limit (bbuf_tmp.position() + maxTransfer); 
bbuf_dest.put (bbuf_tmp); 

// now discard the data we've copied from the original source (optional) 
bbuf_src.position(bbuf_src.position() + maxTransfer);