- package foo;
- import java.io.IOException;
- import java.nio.ByteBuffer;
- import java.nio.CharBuffer;
- import java.nio.charset.Charset;
- /**
- ByteBuffer 並且這三個指針的關係是 position<=limit<=capacity.
- position是當前讀寫的位置。
- limit是最大能讀寫的位置。
- capacity是緩存的容量。
- */
- public class App {
- public static void main(String[] args) throws IOException {
- test001();
- test002();
- test003();
- if (true) {
- return;
- }
- // 創建一個capacity爲256的ByteBuffer
- ByteBuffer buf = ByteBuffer.allocate(256);
- while (true) {
- // System.out.println("input:");
- // 從標準輸入流讀入一個字符
- int c = System.in.read();
- // 當讀到輸入流結束時,退出循環
- if (c == -1)
- break;
- // 把讀入的字符寫入ByteBuffer中
- buf.put((byte) c);
- // 當讀完一行時,輸出收集的字符
- if (c == '\n') {
- // 調用flip()使limit變爲當前的position的值,position變爲0,
- // 爲接下來從ByteBuffer讀取做準備
- buf.flip();
- // 構建一個byte數組
- byte[] content = new byte[buf.limit()];
- // 從ByteBuffer中讀取數據到byte數組中
- buf.get(content);
- // 把byte數組的內容寫到標準輸出
- System.out.print(new String(content));
- // 調用clear()使position變爲0,limit變爲capacity的值,
- // 爲接下來寫入數據到ByteBuffer中做準備
- buf.clear();
- }
- }
- }
- private static void test003() {
- ByteBuffer buffer = ByteBuffer.allocate(16);
- System.out.println("ByteBuffer :");
- System.out.println("capacity:" + buffer.capacity());
- buffer.put(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
- 14, 15 });
- System.out.println("put byte[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15} into buffer.");
- System.out.println("limit:" + buffer.limit());
- System.out.println("position:" + buffer.position());
- buffer.flip();// 數據由寫轉爲讀取
- System.out.println("ByteBuffer 執行flip,轉爲讀取");
- byte[] dst = new byte[10];
- buffer.get(dst, 0, dst.length);
- System.out.println(String.format(
- "byte[]:%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", dst[0], dst[1], dst[2],
- dst[3], dst[4], dst[5], dst[6], dst[7], dst[8], dst[9]));
- System.out.println("讀取完10個字節的數據後:");
- System.out.println("limit:" + buffer.limit());
- System.out.println("position:" + buffer.position());
- buffer.rewind();
- System.out.println("執行rewind,重新讀取數據");
- System.out.println("limit:" + buffer.limit());
- System.out.println("position:" + buffer.position());
- byte[] dt = new byte[10];
- buffer.get(dt, 0, dst.length);
- System.out.println(String.format(
- "byte[]:%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", dt[0], dt[1], dt[2],
- dt[3], dt[4], dt[5], dt[6], dt[7], dt[8], dt[9]));
- System.out.println("讀取完10個字節的數據後:");
- System.out.println("limit:" + buffer.limit());
- System.out.println("position:" + buffer.position());
- System.out.println("在當前位置做標記mark");
- buffer.mark();
- buffer.get();
- buffer.get();
- buffer.get();
- System.out.println("讀取3個字節後position:" + buffer.position());
- // buffer.rewind();
- buffer.reset();
- System.out.println("執行reset後position的位置:" + buffer.position());
- // buffer.clear();
- // System.out.println(buffer.get(3));
- buffer.compact();
- System.out.println("取出10個字節後,執行完compact後ByteBuffer第一個字節:"+buffer.get(0));
- }
- // capacicty:作爲一個內存塊,Buffer有一個固定的大小值,也叫“capacity”.
- // 你只能往裏寫capacity個byte、long,char等類型。一旦Buffer滿了,需要將其清空(通過讀數據或者清除數據)才能繼續寫數據往裏寫數據。
- // position
- // 當你寫數據到Buffer中時,position表示當前的位置。初始的position值爲0.當一個byte、long等數據寫到Buffer後,
- // position會向前移動到下一個可插入數據的Buffer單元。position最大可爲capacity – 1.
- // 當讀取數據時,也是從某個特定位置讀。當將Buffer從寫模式切換到讀模式,position會被重置爲0.
- // 當從Buffer的position處讀取數據時,position向前移動到下一個可讀的位置。
- // limit
- // 在寫模式下,Buffer的limit表示你最多能往Buffer裏寫多少數據。 寫模式下,limit等於Buffer的capacity。
- // 當切換Buffer到讀模式時,
- // limit表示你最多能讀到多少數據。因此,當切換Buffer到讀模式時,limit會被設置成寫模式下的position值。
- // 換句話說,你能讀到之前寫入的所有數據(limit被設置成已寫數據的數量,這個值在寫模式下就是position)
- // flip
- // flip方法將Buffer從寫模式切換到讀模式。調用flip()方法會將position設回0,並將limit設置成之前position的值。
- // 換句話說,position現在用於標記讀的位置,limit表示之前寫進了多少個byte、char等 —— 現在能讀取多少個byte、char等。
- // rewind
- // 將position設回0,所以你可以重讀Buffer中的所有數據。limit保持不變,仍然表示能從Buffer中讀取多少個元素(byte、char等)。
- // 一旦讀完Buffer中的數據,需要讓Buffer準備好再次被寫入。可以通過clear()或compact()方法來完成。
- // clear
- // 如果調用的是clear()方法,position將被設回0,limit被設置成 capacity的值。換句話說,Buffer
- // 被清空了。Buffer中的數據並未清除,只是這些標記告訴我們可以從哪裏開始往Buffer裏寫數據。
- // 如果Buffer中有一些未讀的數據,調用clear()方法,數據將“被遺忘”,意味着不再有任何標記會告訴你哪些數據被讀過,哪些還沒有。
- // compact
- // 如果Buffer中仍有未讀的數據,且後續還需要這些數據,但是此時想要先先寫些數據,那麼使用compact()方法。
- // compact()方法將所有未讀的數據拷貝到Buffer起始處。然後將position設到最後一個未讀元素正後面。limit屬性依然像clear()方法一樣,設置成capacity。現在Buffer準備好寫數據了,但是不會覆蓋未讀的數據。
- private static void test002() {
- ByteBuffer buffer = ByteBuffer.allocate(5);
- System.out.println("初始化:"+buffer.position());
- System.out.println("初始化:"+buffer.limit());
- System.out.println("初始化:"+buffer.capacity());
- System.out.println();
- buffer.put((byte)1);
- System.out.println("放入1個字節:"+buffer.position());
- System.out.println("放入1個字節:"+buffer.limit());
- System.out.println("放入1個字節:"+buffer.capacity());
- System.out.println();
- buffer.flip();
- System.out.println("flip之後:"+buffer.position());
- System.out.println("flip之後:"+buffer.limit());
- System.out.println("flip之後:"+buffer.capacity());
- System.out.println();
- buffer.get();
- System.out.println("拿出一個字節:"+buffer.position());
- System.out.println("拿出一個字節:"+buffer.limit());
- System.out.println("拿出一個字節:"+buffer.capacity());
- }
- private static void test001() {
- String str = "helloWorld";
- ByteBuffer buff = ByteBuffer.wrap(str.getBytes());
- System.out.println("position:"+buff.position()+"\t limit:"+buff.limit());
- //讀取兩個字節
- buff.get();
- buff.get();
- System.out.println("position:"+ (char)buff.get(buff.position())+"\t limit:"+buff.limit());
- buff.mark();
- System.out.println("position:"+buff.position()+"\t limit:"+buff.limit());
- buff.flip();
- System.out.println("position:"+buff.position()+"\t limit:"+buff.limit());
- }
- public static byte[] getBytes (char[] chars) {//將字符轉爲字節(編碼)
- Charset cs = Charset.forName ("UTF-8");
- CharBuffer cb = CharBuffer.allocate (chars.length);
- cb.put (chars);
- cb.flip ();
- ByteBuffer bb = cs.encode (cb);
- return bb.array();
- }
- public static char[] getChars(byte[] bytes) {// 將字節轉爲字符(解碼)
- Charset cs = Charset.forName("UTF-8");
- ByteBuffer bb = ByteBuffer.allocate(bytes.length);
- bb.put(bytes);
- bb.flip();
- CharBuffer cb = cs.decode(bb);
- return cb.array();
- }
- }