Nhận mảng byte từ ByteBuffer trong java


95

Đây có phải là cách được khuyến nghị để lấy byte từ ByteBuffer không

ByteBuffer bb =..

byte[] b = new byte[bb.remaining()]
bb.get(b, 0, b.length);

Câu trả lời:


107

Phụ thuộc vào những gì bạn muốn làm.

Nếu những gì bạn muốn là truy xuất các byte còn lại (giữa vị trí và giới hạn), thì những gì bạn có sẽ hoạt động. Bạn cũng có thể làm:

ByteBuffer bb =..

byte[] b = new byte[bb.remaining()];
bb.get(b);

tương đương theo javadocs của ByteBuffer .


6
Chính xác. Và lưu ý rằng bb.capacity() có thể bằng nhau bb.remaining()ngay cả khi mảng hỗ trợ dài hơn, vì vậy bạn không được sử dụng bằng nhau của chúng để kiểm tra xem khi nào bb.array()là đúng. Thấy chưa ByteBuffer.slice().
cdunn2001 26/09/12

1
Lưu ý rằng, để tránh thay đổi vị trí của bộ đệm, tôi đã sử dụng bb.slice().remaining(). Bằng cách đó, nó trông giống như một bãi chứa sạch mà không cần chạm vào bộ đệm ban đầu.
Kyll

phương pháp này cung cấp cho tôi các byte đã ký tuy nhiên tôi muốn không dấu ... bất kỳ ý tưởng nào?
H Raval

Java không có khái niệm về số nguyên không dấu, chỉ những số có dấu. Nếu bạn muốn "byte không dấu", bạn cần ép kiểu intvà sử dụng mặt nạ bit: int unsigned_byte = b[k] & 0xff;cho một số giá trị của k.
Jason S

Nếu bạn muốn nhận toàn bộ bộ đệm vào một mảng byte, bạn sẽ gọi ByteBuffer#cleartrước?
Kenny Worden

21

Lưu ý rằng bb.array () không tôn trọng vị trí bộ đệm byte và thậm chí có thể tồi tệ hơn nếu bộ đệm byte bạn đang làm việc là một phần của một số bộ đệm khác.

I E

byte[] test = "Hello World".getBytes("Latin1");
ByteBuffer b1 = ByteBuffer.wrap(test);
byte[] hello = new byte[6];
b1.get(hello); // "Hello "
ByteBuffer b2 = b1.slice(); // position = 0, string = "World"
byte[] tooLong = b2.array(); // Will NOT be "World", but will be "Hello World".
byte[] world = new byte[5];
b2.get(world); // world = "World"

Đó có thể không phải là những gì bạn định làm.

Nếu bạn thực sự không muốn sao chép mảng byte, cách giải quyết có thể là sử dụng arrayOffset () + còn lại () của bộ đệm byte, nhưng điều này chỉ hoạt động nếu ứng dụng hỗ trợ chỉ mục + độ dài của bộ đệm byte nó. nhu cầu.


"bb.array () không tôn trọng vị trí bộ đệm byte", bạn có thể cung cấp cho chúng tôi thêm chi tiết về phần này. Tôi hiểu ví dụ lát nhưng cần biết thêm chi tiết về việc tại sao bb.array () mess lên
kkrishnaai

5

Đơn giản vậy thôi

  private static byte[] getByteArrayFromByteBuffer(ByteBuffer byteBuffer) {
    byte[] bytesArray = new byte[byteBuffer.remaining()];
    byteBuffer.get(bytesArray, 0, bytesArray.length);
    return bytesArray;
}

4
final ByteBuffer buffer;
if (buffer.hasArray()) {
    final byte[] array = buffer.array();
    final int arrayOffset = buffer.arrayOffset();
    return Arrays.copyOfRange(array, arrayOffset + buffer.position(),
                              arrayOffset + buffer.limit());
}
// do something else

4

Nếu một người không biết bất kỳ điều gì về trạng thái bên trong của Bộ đệm Byte (Trực tiếp) đã cho và muốn truy xuất toàn bộ nội dung của bộ đệm, thì có thể sử dụng điều này:

ByteBuffer byteBuffer = ...;
byte[] data = new byte[byteBuffer.capacity()];
((ByteBuffer) byteBuffer.duplicate().clear()).get(data);

ByteBuffer.get(byte[])trả về aByteBuffer
pyb

Và ...? Không chắc ý của bạn, xin lỗi.
Tomáš Myšík

Câu hỏi đặt ra là làm thế nào để chuyển từ ByteBuffer sang byte [].
pyb

2
Sau khi được gọi, chúng ở trong databiến. Getter quay trở lại this, hãy xem Javadoc của nó.
Tomáš Myšík

Cảm ơn, tôi không hiểu. Vì phương thức get đang trả về một giá trị, tôi không mong đợi nó cũng có tác dụng phụ.
pyb

1

Đây là một cách đơn giản để lấy byte [], nhưng một phần quan điểm của việc sử dụng ByteBuffer là tránh phải tạo byte []. Có lẽ bạn có thể lấy bất cứ thứ gì bạn muốn từ byte [] trực tiếp từ ByteBuffer.


15
Nhưng thường thì bạn sẽ cần gọi một thứ gì đó (không phải trong mã của riêng bạn) chiếm một byte [], vì vậy việc chuyển đổi không phải là tùy chọn.
James Moore
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.