createtempfile - files java nio
transferir bytes de un ByteBuffer a otro (3)
¿Cuál es la forma más eficiente de poner tantos bytes como sea posible desde un bbuf_src
en otro ByteBuffer bbuf_dest
(así como saber cuántos bytes se transfirieron)? Estoy intentando bbuf_dest.put(bbuf_src)
pero parece querer lanzar una BufferOverflowException y no puedo obtener los javadocs de Sun en este momento (problemas de red) cuando los necesito. > :( argh.
edit: darnit, @ El enfoque de Richard (use put () desde la matriz de respaldo de bbuf_src
) no funcionará si bbuf_src es un búfer ReadOnly, ya que no puede obtener acceso a esa matriz. ¿Qué puedo hacer en ese caso?
OK, he adaptado la respuesta de @ 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;
}
y una prueba para asegurarse de que funciona:
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;
}
Obtiene BufferOverflowException porque su bbuf_dest no es lo suficientemente grande.
Tendrá que usar bbuf_dest.remaining () para averiguar la cantidad máxima de bytes que puede transferir desde bbuf_src:
int maxTransfer = Math.min(bbuf_dest.remaining(), bbuf_src.remaining());
bbuf_dest.put(bbuf_src.array(), 0, maxTransfer);
Como ha descubierto, obtener la matriz de respaldo no siempre funciona (falla para los búferes de solo lectura, los búferes directos y los búferes de archivos mapeados en la memoria). La mejor alternativa es duplicar el almacenamiento intermedio de origen y establecer un nuevo límite para la cantidad de datos que desea transferir:
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);