2013-08-21 10 views
15

Próbuję wyciąć tablicę bajtów, aby wyczyścić pierwszą część tablicy. Używam ByteBuffer, ale nie zachowuje się tak, jak bym się spodziewał.Krojenie tablic bajtowych w Javie

byte[] myArray = new byte[10]; 
ByteBuffer buf = ByteBuffer.wrap(myArray); 
buf.position(5); 
ByteBuffer slicedBuf = buf.slice(); 
byte[] newArray = slicedBuf.array(); 

Spodziewam się, że rozmiar newArray będzie 5, zawierający tylko ostatnią część mojego ByteBuffer. Zamiast tego zwracana jest pełna tablica bajtów. Rozumiem, że dzieje się tak dlatego, że "bufor zabezpieczający" jest taki sam przez cały czas.

Jak wyciąć, aby mieć tylko żądaną część tablicy?

EDIT: Dodano kontekst

Bajty są odbierane z sieci. Bufor jest utworzony w następujący sposób:

[ SHA1 hash ] [ data... lots of it ]

już posiada funkcję, której tablicy bajtów jako parametr i obliczenia mieszania SHA1. To, czego chcę, to wyciąć pełny bufor, aby przekazać tylko dane bez oczekiwanego skrótu.

+0

Jeśli nie napisałeś funkcji haszowania, utkniesz, gdy masz wszystko w jednym bajcie [], jeśli chcesz uniknąć kopii. Dlaczego nie odczytać hasha z sieci do jednej tablicy, a dane do innej? –

Odpowiedz

45

Można użyć metody Arrays.copyOfRange. Na przykład:

// slice from index 5 to index 9 
byte[] slice = Arrays.copyOfRange(myArray, 5, 10); 
+0

Dziękuję za odpowiedź. Czy wiesz, czy jest jakiś sposób, aby to zrobić bez kopiowania? Moja tablica może osiągnąć wiele megabajtów, więc wolałabym unikać kopiowania, jeśli to możliwe. – Eric

+0

Bajty w tablicach bajtowych nie mogą być ponownie użyte przez różne tablice. W tym celu masz klasę 'ByteBuffer'. Ewentualnie zmień funkcję SHA1, aby akceptowała przesunięcie i długość plasterka oprócz macierzy. – Joni

+0

Nie sądzę, żebym mógł zmienić moje hash algo, ponieważ jest to javax.crypto.mac. Nie mam kontroli nad parametrami do niego przekazywanymi. – Eric

5

Utworzony przez ciebie ByteBuffer jest wspierany przez tę tablicę. Podczas rozmowy telefonicznej slice() skutecznie otrzymać konkretną widok tych danych:

tworzy nowy bufor bajtowy, którego treść jest wspólny podciąg zawartości tego bufora.

Dlatego wywołanie array() na zwróconym ByteBuffer zwraca tablicę podkładową w całości.

aby wyodrębnić wszystkie bajty z tym poglądem, można zrobić:

byte[] bytes = new byte[slicedBuf.remaining()]; 
slicedBuf.read(bytes); 

Bajty z tego względu będą kopiowane do nowej tablicy.

Edytuj, aby dodać od komentarzach poniżej: Warto zauważyć, że jeśli wszystko jesteś zainteresowany w tym jest kopiowanie bajtów z jednego do innego byte[]byte[], nie ma powodu, aby użyć ByteBuffer; po prostu skopiuj bajty.

+0

Zasadniczo, jeśli w twojej odpowiedzi znajduje się słowo 'ByteBuffer', jest to zła odpowiedź.Zobacz odpowiedź Joni'ego na odpowiedź łykową (i tylko do przyjęcia IMHO). – Bohemian

+2

Odpowiedziałem na pytanie PO, a nie na interpretację jego intencji. Ponadto, jeśli twoja odpowiedź nie zawiera żadnych treści wyjaśniających działanie * dlaczego *, jest to zła odpowiedź. –

+0

Tak, dziękuję za odpowiedź. Przesyłam kod z C i nie mam tam żadnego kopiowania, tylko manipulację wskaźnikami, więc spodziewałem się czegoś podobnego w Javie. Moja tablica może osiągnąć wiele megabajtów, więc kopiowanie jest dość nieekonomiczne – Eric

Powiązane problemy