Mục đích của phương pháp lật ByteBuffer là gì? (Và tại sao nó được gọi là "lật"?)


95

Tại sao phương thức flip () của ByteBuffer được gọi là "flip"? "Lộn" ở đây là gì? Theo apidoc, hai lần lật liên tiếp sẽ không khôi phục lại trạng thái ban đầu và nhiều lần lật có thể sẽ limit()trở thành số không.

Tôi có thể "mở" bằng cách nào đó để sử dụng lại các byte đã vượt quá giới hạn không?

Tôi có thể nối đuôi được lật với một số dữ liệu khác không?


5
Nó "lật" bộ đệm từ đọc sang ghi (và ngược lại). thushw.blogspot.com/2009/10/…
Brian Roach

2
@BrianRoach: Nó chuyển từ đọc sang ghi nhưng không hữu ích cho việc ghi sang đọc trừ khi bạn đang viết các cấu trúc có kích thước cố định. Để lật để viết để đọc, hãy sử dụng resetthay thế.
nneonneo

Hãy nhớ đặt những câu hỏi "khách quan"; hoặc, ít nhất, làm cho các câu hỏi chủ yếu có vẻ khách quan: D

@nneonneo - Nó không phải là một câu hỏi, sẽ không thực sự dành nhiều thời gian để giải thích các chi tiết, do đó chỉ là một nhận xét và một liên kết.
Brian Roach,

Câu trả lời:


130

Một trường hợp sử dụng khá phổ biến ByteBufferlà xây dựng từng phần một cấu trúc dữ liệu và sau đó ghi toàn bộ cấu trúc đó vào đĩa. flipđược sử dụng để lật ByteBuffertừ "đọc từ I / O" ( putting) sang "ghi vào I / O" ( getting): sau khi một chuỗi puts được sử dụng để điền vào ByteBuffer, flipsẽ đặt giới hạn của bộ đệm ở vị trí hiện tại và đặt lại vị trí về không. Điều này có tác dụng tạo ra một tương lai gethoặc writetừ bộ đệm ghi tất cả những gì đã có putvào bộ đệm và không còn nữa.

Sau khi hoàn thành put, bạn có thể muốn sử dụng lại ByteBufferđể xây dựng một cấu trúc dữ liệu khác. Để "mở" nó, hãy gọi clear. Điều này đặt lại giới hạn dung lượng (làm cho tất cả bộ đệm có thể sử dụng được) và vị trí thành 0.

Vì vậy, một kịch bản sử dụng điển hình:

ByteBuffer b = new ByteBuffer(1024);
for(int i=0; i<N; i++) {
    b.clear();
    b.put(header[i]);
    b.put(data[i]);
    b.flip();
    out.write(b);
}

Một loại là outgì?
Suzan Cioc

6
Hoặc bất cứ điều gì khác có một write(ByteBuffer)phương pháp. (Nó không phải là thực sự có liên quan gì loại của nó là ...)
Stephen C

1
Nó sẽ Buffer.clearđặt lại giới hạn dung lượng và vị trí thành 0. Buffer.resetchỉ đặt lại vị trí thành mark.
Kelvin Ng

1
@KelvinNg: Bạn nói đúng; Tôi đã sửa đổi câu trả lời để phản ánh điều này. Cảm ơn vì bắt tốt!
nneonneo

1
@ user963241: đọc từ I / O vào bộ đệm, ghi từ bộ đệm vào I / O.
nneonneo

7

Flip gán giá trị vị trí hiện tại cho thuộc tính giới hạn và đặt thuộc tính vị trí thành 0. Flip rất hữu ích để chỉ rút các phần tử đang hoạt động khỏi bộ đệm.

Ví dụ, chương trình dưới đây in ra "hello" không phải là phần tử trống của bộ đệm. Giới hạn và vị trí cuộc gọi phương thức có thể được thay thế bằng lật.

CharBuffer cbuff = CharBuffer.allocate(40);
cbuff.put("hello"); 
// what below two line of code is what flip does
cbuff.limit(cbuff.position());
cbuff.position(0);      
while(cbuff.hasRemaining()) {
    System.out.println(cbuff.get());
}

Xem http://www.zoftino.com/java-nio-tutorial để biết thêm thông tin về bộ đệm và kênh.


Cảm ơn bạn đã liên kết đến phạm vi bảo hiểm rất rộng rãi! Thật tuyệt khi các nguồn được đưa vào. Các tài liệu API java dường như sử dụng từ 'lật' mà không cần giải thích, như thể nó là một thuật ngữ khoa học máy tính phổ biến, nhưng rõ ràng là một vài người (bao gồm cả tôi) không nhận ra điều đó đúng.
John Meyer

3

ByteBuffer không được thiết kế. Có rất nhiều lời phàn nàn từ các lập trình viên tử tế.

Vì vậy, đừng cố lý luận về nó, chỉ cần nghiên cứu và sử dụng API một cách cẩn thận.

Bây giờ tôi không thể nói xấu nó mà không trình bày một giải pháp thay thế, vì vậy đây là:

Một bộ đệm có một cố định capacity; nó duy trì 2 con trỏ: startend. get()trả về byte tại startvị trí và gia số start. put()đặt byte ở endvị trí và gia số end. Không flip()!


6
Vì vậy, những gì là khiếu nại? Nếu bạn có một số phàn nàn cá nhân thì cũng không sao, nhưng bạn không nên chỉ nói "X API tệ quá, mọi người đã nói vậy".
nneonneo

13
Đăng liên kết đó thực sự là tất cả những gì bạn phải làm ngay từ đầu. Tôi không bao giờ buộc tội bạn nói dối, tôi chỉ yêu cầu bạn nói rõ hơn về nguồn gốc và bản chất của các khiếu nại.
nneonneo

2
đây chỉ là nơi mọi người tự nguyện đề nghị giúp đỡ với mức độ nỗ lực thích hợp mà họ chọn. Tôi không cần phải mở rộng mỗi câu trả lời thành một bài báo học thuật được nghiên cứu kỹ lưỡng.
chối cãi

8
và đây cũng là nơi mà mọi người sẽ không nghe lời ai đó trừ khi nghe có vẻ đáng tin cậy.
arunmoezhi

8
Bạn thậm chí không cần phải cung cấp các nguồn. Rõ ràng là ByteBuffer được thiết kế không tốt. lật không có mục đích, nó chỉ tạo ra một nguồn lỗi khi bạn quên lật. Nếu họ cảm thấy thôi thúc không thể kiểm soát để đưa nó vào, ít nhất hãy tạo các lớp ByteBuffers đã lật và chưa lật khác nhau, để hệ thống loại có thể bắt lỗi.
Gurgeh

0

Phương thức flip () làm cho một bộ đệm sẵn sàng cho một chuỗi hoạt động ghi kênh hoặc lấy tương đối mới: Nó đặt giới hạn cho vị trí hiện tại và sau đó đặt vị trí bằng không.

Bộ đệm theo dõi dữ liệu được ghi vào đó. Phương thức viết bài, flip () được gọi để chuyển từ chế độ ghi sang chế độ đọc.

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.