java.nio.ByteBuffer#duplicate()
zwraca nowy bufor bajtowy, który udostępnia zawartość starego bufora. Zmiany w zawartości starego bufora będą widoczne w nowym buforze i na odwrót. Co się stanie, jeśli chcę mieć głęboką kopię bufora bajtowego?Duplikat kopii głębokiej() Javy ByteBuffer
Odpowiedz
Będziesz musiał powtórzyć cały bufor i skopiować według wartości do nowego bufora.
Myślę, że kopia nie musi zawierać byte[]
. Spróbuj wykonać następujące czynności:
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;
}
Dlaczego muszę odwrócić klon? Wtedy limit jest niższy niż moja prawdziwa pojemność – Karussell
WOW! To było pomocne. Dzięki! –
Jedyną rzeczą, która nie została skopiowana w tym przypadku, jest znak, więc po prostu wiedz, że jeśli użyjesz znaku, zostanie utracone. Ponadto ta funkcja kopiuje tylko od początku do limitu, a pozycja oryginału jest tracona, sugerowałbym ustawienie position = 0 i limit = capacity i przechowywanie ich jako zmiennych tymczasowych, które mają być zresetowane na oryginale i sklonowane przed powrotem. Również przewijanie odrzuca znak, więc użycie tego prawdopodobnie nie jest dobrym pomysłem. Opublikuję odpowiedź bardziej kompletną metodą. – LINEMAN78
oparciu off roztworu mingfai za:
To daje prawie prawdziwą głęboką kopię. Jedyną rzeczą utraconą będzie znak. Jeśli orig jest HeapBuffer, a offset nie jest równy zeru lub pojemność jest mniejsza niż tablica backingowa, niż nie są kopiowane odległe dane.
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);
}
}
Ponieważ kwestia ta nadal pojawia się jako jeden z pierwszych hitów do kopiowania ByteBuffer
, złożę moje rozwiązanie. To rozwiązanie nie dotyka oryginalnego bufora, w tym żadnego zestawu znaczników, i zwróci głęboką kopię o takiej samej pojemności, jak oryginał.
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;
}
Jeśli dba o położeniu, ogranicza, lub aby być ustawione tak samo, jak w oryginale, to jest to łatwe, oprócz wyżej wymienionych:
clone.position(original.position());
clone.limit(original.limit());
clone.order(original.order());
return clone;
Dlaczego nie 'clone.put (readOnlyCopy)' zamiast pośredniej tablicy 'byte'? – seh
@seh Ponieważ byłem głupi i nie widziałem tej metody. Dziękuję za wskazanie. – jdmichal
To jest najlepsze rozwiązanie. Nie modyfikuje oryginalnej zawartości i zapewnia najczystsze sposoby robienia tego samego. –
jedno proste rozwiązanie
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. C: Dokonywanie głębokiej kopii struktury ... robienie płytkiej kopii struktury
- 2. env.Clone() w scons nie wykonuje kopii głębokiej
- 3. Pisanie głębokiej kopii - kopiowanie wartości wskaźnika
- 4. Ogólna metoda tworzenia głębokiej kopii wszystkich elementów w kolekcji
- 5. Ciągnięcie danych z CMSampleBuffer w celu utworzenia głębokiej kopii
- 6. Manipulacja ByteBuffer z JNI
- 7. Czyszczenie ByteBuffer
- 8. Jeśli chcę nierekurencyjnej głębokiej kopii mojego obiektu, czy powinienem przesłonić kopię lub deepcopy w Pythonie?
- 9. Czy obiekty pchane do tablicy w głębokiej lub płytkiej kopii javascript?
- 10. C++ odpowiednik Java ByteBuffer?
- 11. Problem z wydajnością Java ByteBuffer
- 12. Duplikat virtualenv
- 13. Java/Android - Szybka analiza ByteBuffer
- 14. Określ liczbę bajtów w ByteBuffer
- 15. Dostęp do Javy Javy z Delphi
- 16. Czy istnieje bezpieczny sposób pobrania Javy Javy?
- 17. Nieprawidłowe zachowanie Javy w instancji Javy
- 18. Javascript duplikat detektor kodu?
- 19. Usuń duplikat w MongoDB
- 20. Usuń duplikat z tabeli
- 21. Typescript Duplikat Realizacja funkcji
- 22. Duplikat błędu definicji klasy
- 23. Duplikat rekordu w MySQL
- 24. duplikat błędu symbolu C++
- 25. Złap duplikat wpisu Wyjątek
- 26. wskaźniki - duplikat obiektu instancji
- 27. phpMyAdmin Duplikat tabeli
- 28. postgreSQL: jak duplikat wiersz
- 29. Duplikat nazwa kolumny
- 30. Jak umieścić zawartość ByteBuffer w OutputStream?
Istnieje (opcjonalne) przeciążenie metody 'put', która robi to za Ciebie. – nos
Woohoo! Nauczyłem się czegoś nowego. – Kylar