2013-05-09 46 views
16

Tôi biết rằng flip() đặt vị trí bộ đệm hiện tại thành 0 và đặt giới hạn cho vị trí đệm trước đó trong khi tua lại() chỉ cần đặt vị trí bộ đệm hiện tại thành 0.Sự khác biệt giữa bytebuffer.flip() và bytebuffer.rewind()

Trong mã sau, tôi sử dụng tua lại() hoặc lật() tôi nhận được kết quả tương tự.

byte b = 127; 
bb.put(b); 
bb.rewind();//or flip(); 

System.out.println(bb.get()); 
bb.rewind();// or flip(); 
System.out.println(bb.get()); 

Bạn có thể cho tôi ví dụ thực sự về sự khác biệt của 2 phương pháp này thực sự quan trọng không? Cảm ơn trước. EDIT: Tôi tìm thấy giải pháp trong liên kết this, nó được giải thích rất kỹ và chi tiết để hiểu rõ về việc sử dụng bộ đệm và kênh.

Trả lời

7

Chúng hoàn toàn không tương đương.

A ByteBuffer thường sẵn sàng cho read() (hoặc cho put()).

flip() làm cho nó sẵn sàng cho write() (hoặc cho get()).

rewind()compact()clear() làm cho nó sẵn sàng cho read()/put() một lần nữa sau khi write() (hoặc get()).

+0

bạn có thể vui lòng cho tôi biết tại sao bạn lại viết 'read()/put() 'và' write()/nhận được () '? Nó không phải là 'read()/get()' và 'write()/put()'? Kể từ khi nhận được hoạt động có nghĩa là đọc và đặt ngụ ý bằng văn bản? – user963241

1

Phương thức rewind() tương tự như lật() nhưng không ảnh hưởng đến giới hạn. Nó chỉ thiết lập vị trí quay lại 0. Bạn có thể sử dụng rewind() để quay trở lại và đọc lại dữ liệu trong bộ đệm đã được lật. Một tình huống phổ biến sẽ là: sau khi bạn sử dụng flip(), bạn đọc dữ liệu từ bộ đệm, bạn muốn đọc lại dữ liệu, phương thức này sẽ hoạt động.

1

Đây là ví dụ trong đó hai sản phẩm sẽ tạo ra các kết quả khác nhau. Như bạn đã nói, cả hai thiết lập vị trí 0, sự khác biệt giữa hai là lật thiết lập giới hạn cho vị trí trước đó.

Vì vậy, với lật, nếu bạn đang viết (đặt), giới hạn đọc (nhận) sẽ trở thành vị trí của phần tử cuối cùng bạn đã viết. Nếu bạn cố gắng đọc nhiều hơn thế, nó sẽ ném một ngoại lệ.

Tua lại để lại giới hạn không thay đổi. Giả sử nó có dung lượng (kích thước bộ đệm), nó sẽ cho phép bạn tiếp tục đọc trên dữ liệu mà bạn thực sự đã viết, trong trường hợp này đọc các số 0 ban đầu mà bộ đệm được khởi tạo với.

ByteBuffer bb = ByteBuffer.allocateDirect(2); 
byte b = 127; 
bb.put(b); 
bb.rewind();//or flip(); 

System.out.println(bb.get()); // will print 127 in either case 
System.out.println(bb.get()); // will print 0 for rewind, BufferUnderflow exception for flip 
2

Từ mã nguồn, chúng rất giống nhau. Bạn sẽ nhìn thấy sau:

public final Buffer flip() { 
    limit = position; 
    position = 0; 
    mark = -1; 
    return this; 
} 

public final Buffer rewind() { 
    position = 0; 
    mark = -1; 
    return this; 
} 

Vì vậy, sự khác nhau là flip thiết lập limit-position, trong khi rewind không. xem xét bạn đã phân bổ một bộ đệm với 8 kích thước, bạn đã điền bộ đệm với 4 byte, sau đó vị trí được thiết lập để 3, chỉ hiển thị như sau:

[ 1 1 1 1 0 0 0 0] 
       |   | 
flip   limit  | 
rewind      limit 

Vì vậy rewind chỉ được sử dụng giới hạn đã đặt phù hợp.

0

@ user963241 Để thêm nhiều màu hơn vào câu trả lời của @ EJP.

lật() làm cho nó sẵn sàng cho write() (hoặc cho get())

get() Ví dụ;

Bạn có thể muốn đọc dữ liệu từ bộ đệm (giả định rằng bạn đã bước đầu được lưu trữ nó trong đó) và sử dụng nó cho cái gì khác chẳng hạn như chuyển đổi thành một chuỗi và vận dụng nó để sử dụng tiếp.

ByteBuffer buf = ByteBuffer.allocateDirect(80); 
private String method(){ 
buf.flip(); 
byte[] bytes = byte[10]; //creates a byte array where you can place your data 
buf.get(bytes); //reads data from buffer and places it in the byte array created above 
return bytes; 
} 

write() Ví dụ; Sau khi bạn đã đọc dữ liệu từ kênh ổ cắm vào bộ đệm, bạn có thể muốn ghi nó trở lại kênh socket - giả sử rằng bạn muốn triển khai một cái gì đó giống như một máy chủ có cùng thông điệp nhận được từ máy khách.

Vì vậy, bạn sẽ đọc từ kênh để đệm và từ đệm trở lại kênh

SocketChannel socketChannel = SocketChannel.open(); 
... 

ByteBuffer buf = ByteBuffer.allocateDirect(80); 

int data = socketChannel.read(buf); // Reads from channel and places it into the buffer 
while(data != -1){ //checks if not end of reading 
buf.flip();  //prepares for writing 
.... 
socketChannel.write(buf) // if you had initially placed data into buf and you want to read 
         //from it so that you can write it back into the channel 


    } 
Các vấn đề liên quan