2013-08-21 45 views
15

Tôi đang cố gắng cắt một mảng byte để cắt bớt phần đầu tiên của mảng. Tôi đang sử dụng ByteBuffer nhưng nó không hoạt động như tôi mong đợi.Cắt mảng byte trong Java

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

Tôi mong đợi kích thước của newArray là 5, chỉ chứa phần cuối cùng của ByteBuffer của tôi. Thay vào đó, mảng byte đầy đủ được trả về. Tôi hiểu rằng điều này là do "đệm đệm" giống nhau.

Làm cách nào tôi có thể cắt để chỉ có phần mong muốn của mảng?

EDIT: Đã thêm ngữ cảnh

Các byte được nhận từ mạng. Các bộ đệm được hình thành như thế này:

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

Tôi đã có một chức năng mà phải mất một mảng byte như một tham số và tính toán băm SHA1. Những gì tôi muốn là để cắt bộ đệm đầy đủ để vượt qua chỉ các dữ liệu mà không có băm dự kiến.

+0

Nếu bạn không viết hàm băm, bạn bị mắc kẹt khi bạn có mọi thứ trong một 'byte []' nếu bạn muốn tránh một bản sao. Tại sao không đọc băm từ mạng vào một mảng và dữ liệu vào một mảng khác? –

Trả lời

45

Bạn có thể sử dụng phương thức Arrays.copyOfRange. Ví dụ:

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

Cảm ơn bạn đã trả lời. Bạn có biết nếu có cách nào để làm điều này mà không cần sao chép? Mảng của tôi có thể đạt đến nhiều megabyte vì vậy tôi muốn tránh sao chép nếu có thể – Eric

+0

Các byte trong mảng byte không thể được tái sử dụng bởi các mảng khác nhau. Bạn có lớp 'ByteBuffer' cho mục đích này. Ngoài ra, thay đổi hàm SHA1 của bạn để nó chấp nhận độ lệch và chiều dài cho một lát ngoài mảng. – Joni

+0

Tôi không nghĩ rằng tôi có thể thay đổi algo băm của tôi vì nó là javax.crypto.mac. Tôi không kiểm soát các thông số được truyền cho nó. – Eric

5

ByteBuffer bạn tạo đang được hỗ trợ bởi mảng đó. Khi bạn gọi slice() bạn có hiệu quả nhận được một cụ xem dữ liệu:

Tạo một bộ đệm byte mới mà nội dung là một dãy con chia sẻ nội dung của bộ đệm này.

Do đó, hãy gọi array() trên đó trả về toàn bộ mảng sao lưu.

Để trích xuất tất cả các byte từ quan điểm đó, bạn có thể làm:

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

Các byte từ quan điểm cho rằng sẽ được sao chép vào mảng mới.

Chỉnh sửa để thêm từ ý kiến ​​dưới đây: Nó đáng chú ý rằng nếu tất cả các bạn đang quan tâm đến việc làm là sao chép byte từ một byte[] để byte[] khác, không có lý do để sử dụng một ByteBuffer; chỉ cần sao chép các byte.

+0

Về cơ bản, nếu từ 'ByteBuffer' tồn tại trong câu trả lời của bạn thì đó là câu trả lời không tốt.Xem câu trả lời của Joni cho câu trả lời (và chỉ chấp nhận được IMHO). – Bohemian

+2

Tôi trả lời câu hỏi của OP, chứ không phải là sự giải thích ý định của anh ta. Ngoài ra, nếu câu trả lời của bạn không có bất kỳ nội dung giải thích * tại sao * mọi thứ hoạt động, đó là một câu trả lời không tốt. –

+0

Có, cảm ơn bạn đã trả lời. Tôi đang chuyển mã từ C và tôi không có bất kỳ sao chép ở đó, chỉ thao tác con trỏ vì vậy tôi đã mong đợi một cái gì đó giống nhau trong Java. Mảng của tôi có thể đạt đến nhiều megabyte để sao chép khá lãng phí – Eric