java 将字节从一个 ByteBuffer 传输到另一个

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/570168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 12:53:56  来源:igfitidea点击:

transferring bytes from one ByteBuffer to another

javajavadocnio

提问by Jason S

What's the most efficient way to put as many bytes as possible from a ByteBuffer bbuf_srcinto another ByteBuffer bbuf_dest(as well as know how many bytes were transferred)? I'm trying bbuf_dest.put(bbuf_src)but it seems to want to throw a BufferOverflowException and I can't get the javadocs from Sun right now (network problems) when I need them. >:( argh.

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



edit: darnit, @Richard's approach (use put() from the backing array of bbuf_src) won't work if bbuf_src is a ReadOnly buffer, as you can't get access to that array. What can I do in that case???

编辑:亲爱的,bbuf_src如果 bbuf_src 是只读缓冲区,@Richard 的方法(使用 的后备数组中的 put() )将不起作用,因为您无法访问该数组。这种情况我能怎么办???

采纳答案by Jason S

OK, I've adapted @Richard's answer:

好的,我已经改编了@Richard 的回答:

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;
}

and a test to make sure it works:

并进行测试以确保其有效:

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;
}

回答by Jules

As you've discovered, getting the backing array doesn't always work (it fails for read only buffers, direct buffers, and memory mapped file buffers). The better alternative is to duplicate your source buffer and set a new limit for the amount of data you want to transfer:

正如您所发现的,获取后备数组并不总是有效(对于只读缓冲区、直接缓冲区和内存映射文件缓冲区,它会失败)。更好的选择是复制源缓冲区并为要传输的数据量设置新的限制:

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);

回答by Richard

You get the BufferOverflowException because your bbuf_dest is not big enough.

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

You will need to use bbuf_dest.remaining() to find out the maximum number of bytes you can transfer from bbuf_src:

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

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