java.nio.ByteBuffer#duplicate()
Renvoie un nouveau tampon d'octets qui partage le contenu de l'ancien tampon. Les modifications apportées au contenu de l'ancien tampon seront visibles dans le nouveau tampon, et vice versa. Que faire si je veux une copie profonde du tampon d'octets?Copie en profondeur duplicate() de ByteBuffer Java
Répondre
Vous aurez besoin d'itérer toute la mémoire tampon et de la copier par valeur dans le nouveau tampon.
Je pense que la copie profonde ne doit pas impliquer byte[]
. Effectuez les actions suivantes:
public static ByteBuffer clone(ByteBuffer original) {
ByteBuffer clone = ByteBuffer.allocate(original.capacity());
original.rewind();//copy from the beginning
clone.put(original);
original.rewind();
clone.flip();
return clone;
}
Pourquoi ai-je besoin de retourner le clone? Ensuite, la limite est inférieure à ma capacité réelle – Karussell
WOW! C'était utile.THanks! –
La seule chose qui n'est pas copiée dans ce cas est la marque, alors sachez que si vous utilisez marque, elle sera perdue. De plus, cette fonction copie seulement du début à la limite et la position de l'original est perdue, je suggérerais de mettre position = 0 et limit = capacité et de les stocker comme temp vars à réinitialiser sur original et cloner avant de revenir. Le rembobinage supprime également la marque, ce qui n'est probablement pas une bonne idée. Je posterai une réponse avec une méthode plus complète. – LINEMAN78
Basé hors de la solution de mingfai:
Cela vous donnera une copie en profondeur presque vrai. La seule chose perdue sera la marque. Si orig est un HeapBuffer et que le décalage n'est pas égal à zéro ou que la capacité est inférieure au tableau de sauvegarde, les données périphériques ne sont pas copiées.
public static ByteBuffer deepCopy(ByteBuffer orig)
{
int pos = orig.position(), lim = orig.limit();
try
{
orig.position(0).limit(orig.capacity()); // set range to entire buffer
ByteBuffer toReturn = deepCopyVisible(orig); // deep copy range
toReturn.position(pos).limit(lim); // set range to original
return toReturn;
}
finally // do in finally in case something goes wrong we don't bork the orig
{
orig.position(pos).limit(lim); // restore original
}
}
public static ByteBuffer deepCopyVisible(ByteBuffer orig)
{
int pos = orig.position();
try
{
ByteBuffer toReturn;
// try to maintain implementation to keep performance
if(orig.isDirect())
toReturn = ByteBuffer.allocateDirect(orig.remaining());
else
toReturn = ByteBuffer.allocate(orig.remaining());
toReturn.put(orig);
toReturn.order(orig.order());
return (ByteBuffer) toReturn.position(0);
}
finally
{
orig.position(pos);
}
}
Cette question est encore comme l'un des premiers coups à la copie d'un ByteBuffer
, je proposerai ma solution. Cette solution ne touche pas le tampon d'origine, y compris les marques définies, et renvoie une copie profonde avec la même capacité que l'original.
public static ByteBuffer cloneByteBuffer(final ByteBuffer original) {
// Create clone with same capacity as original.
final ByteBuffer clone = (original.isDirect()) ?
ByteBuffer.allocateDirect(original.capacity()) :
ByteBuffer.allocate(original.capacity());
// Create a read-only copy of the original.
// This allows reading from the original without modifying it.
final ByteBuffer readOnlyCopy = original.asReadOnlyBuffer();
// Flip and read from the original.
readOnlyCopy.flip();
clone.put(readOnlyCopy);
return clone;
}
Si l'on prend soin de la position, limite, ou pour régler le même que l'original, alors c'est un ajout facile au-dessus:
clone.position(original.position());
clone.limit(original.limit());
clone.order(original.order());
return clone;
Pourquoi pas 'clone.put (readOnlyCopy)' au lieu du tableau intermédiaire 'byte'? – seh
@seh Parce que j'étais stupide et n'ai pas vu cette méthode. Merci de l'avoir signalé. – jdmichal
C'est la meilleure solution. Il ne mute pas le contenu original et fournit les moyens les plus propres de faire la même chose. –
Encore une solution simple
public ByteBuffer deepCopy(ByteBuffer source, ByteBuffer target) {
int sourceP = source.position();
int sourceL = source.limit();
if (null == target) {
target = ByteBuffer.allocate(source.remaining());
}
target.put(source);
target.flip();
source.position(sourceP);
source.limit(sourceL);
return target;
}
- 1. Infinite ByteBuffer en Java
- 2. hashtable de copie en profondeur
- 3. C++ équivalent de Java ByteBuffer?
- 4. Java ByteBuffer à C
- 5. Copie en profondeur des entités JPA
- 6. Clone (copie en profondeur) Entité LINQ
- 7. constructeur Copie: copie en profondeur une classe abstraite
- 8. gets tableau d'octets d'un ByteBuffer en Java
- 9. Copie en profondeur des noeuds de la vue arborescente
- 10. Comment faire une copie en profondeur des objets NHibernate?
- 11. Copie en profondeur des beans EJB Entity avec les relations
- 12. Est-ce que Enumerable.Repeat() fait une copie en profondeur?
- 13. Copie superficielle en Java
- 14. Comment faites-vous une copie en profondeur d'un objet dans Java?
- 15. JNA ByteBuffer statvfs
- 16. Profondeur de la première recherche en utilisant Java
- 17. Une opération de copie en profondeur copie-t-elle de manière récursive des sous-variables qu'elle ne possède pas?
- 18. En Perl, comment puis-je faire une copie en profondeur d'un tableau?
- 19. Problème lors de la copie en profondeur d'une 'Liste <T>' C#
- 20. C++: Mise à jour des pointeurs de copie en profondeur (efficacement)
- 21. Copie en profondeur de std :: stack <boost> shared_ptr <T>>
- 22. profondeur de rendu en HLSL
- 23. Profondeur de suivi en récursivité
- 24. ByteBuffer à BIGDECIMAL, binaire, chaîne
- 25. Fogbugz Duplicate Cases
- 26. Django "Duplicate" ModelForm
- 27. Git - Duplicate commit problème
- 28. Clonage en profondeur dans Compact Framework
- 29. Copie de fichiers en Java à l'aide de JNI
- 30. Comment faire une copie en profondeur d'un élément dans LINQ to XML?
Il y a une surcharge (optionnelle) de la méthode 'put' qui fait cela pour vous. – nos
Woohoo! J'ai appris quelque chose de nouveau. – Kylar