2009-02-20 7 views
5

Quel est le moyen le plus efficace de mettre autant d'octets que possible à partir d'un ByteBuffer bbuf_src dans un autre ByteBuffer bbuf_dest (ainsi que de savoir combien d'octets ont été transférés)? J'essaye bbuf_dest.put(bbuf_src) mais il semble vouloir lancer une BufferOverflowException et je ne peux pas obtenir les javadocs de Sun en ce moment (problèmes de réseau) quand j'en ai besoin. > :(arghtransfert d'octets d'un ByteBuffer à un autre


modifier. Darnit, @ approche de Richard (utilisation de vente() du tableau de sauvegarde de bbuf_src) ne fonctionnera pas si bbuf_src est un tampon en lecture seule, comme vous ne pouvez pas avoir accès à ce tableau. que puis-je faire dans ce cas ???

+0

Je pense que vous devriez diviser cela en deux questions. – GEOCHET

+0

l'autre moitié a été déplacée ici: http://stackoverflow.com/questions/570218/downloading-sun-javadocs-mirror-websites –

Répondre

1

OK, je l'ai adapté @ réponse 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; 
} 

et un test pour vous assurer qu'il fonctionne:

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

Vous obtenez le BufferOverflowException parce que votre bbuf_dest est pas assez grand.

Vous devez utiliser bbuf_dest.remaining() pour connaître le nombre maximum de octets vous pouvez transférer de bbuf_src:

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

Ah. C'est utile. Je pense que je sais quoi faire maintenant. Merci. Mais notez que votre réponse ne fonctionnera pas si bbuf_src est un tampon de vue pour un autre tampon. Je pense que je peux l'adapter cependant. –

+0

(ou si la position de bbuf_src est> 0) –

+0

... et je dois également mettre à jour la position de bbuf_src. –

8

Comme vous l'avez découvert, obtenir le tableau de sauvegarde ne sont pas toujours travail (il échoue pour les tampons en lecture seule, les tampons directs et les tampons de fichiers mappés en mémoire). La meilleure alternative est de dupliquer votre tampon source et de définir une nouvelle limite pour la quantité de données que vous souhaitez transférer:

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

Mais Oracle dit que la limite doit être "pas plus grande que la capacité du tampon". Dupliquer un tampon dupliquera sa capacité, n'est-ce pas? –

Questions connexes