передача байтов из одного байт-буфера в другой

StackOverflow https://stackoverflow.com/questions/570168

  •  05-09-2019
  •  | 
  •  

Вопрос

Какой наиболее эффективный способ поместить как можно больше байтов из байт-буфера bbuf_src в другой байтбуфер bbuf_dest (а также знать, сколько байт было передано)?Я пытаюсь bbuf_dest.put(bbuf_src) но, похоже, он хочет вызвать исключение BufferOverflowException, и я не могу получить javadocs от Sun прямо сейчас (проблемы с сетью), когда они мне нужны.>: ( аргх.


Редактировать:дарнит, подход @Richard's (используйте put() из резервного массива bbuf_src) не будет работать, если bbuf_src является буфером только для чтения, так как вы не можете получить доступ к этому массиву.Что я могу сделать в таком случае???

Это было полезно?

Решение 2

Хорошо, я адаптировал ответ @ 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;
}

и тест, чтобы убедиться, что это работает:

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

Другие советы

Как вы обнаружили, получение резервного массива не всегда работает (это не удается для буферов только для чтения, прямых буферов и файловых буферов с отображением в память).Лучшей альтернативой является дублирование вашего исходного буфера и установка нового ограничения на объем данных, которые вы хотите передать:

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

Вы получаете исключение 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);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top