Java NIO -- 緩衝區(Buffer)的資料存取

weixin_34319999發表於2017-06-26

緩衝區(Buffer):

一個用於特定基本資料型別的容器。由 java.nio 包定義的,所有緩衝區都是 Buffer 抽象類的子類。
Java NIO 中的 Buffer 主要用於與 NIO 通道進行互動,資料是從通道讀入緩衝區,從緩衝區寫入通道中的。

Buffer 就像一個陣列,可以儲存多個相同型別的資料。根據資料型別不同(boolean 除外) ,有以下 Buffer 常用子類:
ByteBuffer
CharBuffer
 ShortBuffer
 IntBuffer
 LongBuffer
 FloatBuffer
 DoubleBuffer
上述 Buffer 類 他們都採用相似的方法進行管理資料,只是各自管理的資料型別不同而已。都是通過如下方法獲取一個 Buffer
物件:
static XxxBuffer allocate(int capacity) : 建立一個容量為capacity 的 XxxBuffer 物件

 

緩衝區存取資料的兩個核心方法:

put() : 存入資料到緩衝區中

get() : 獲取緩衝區中的資料

緩衝區中的四個核心屬性:

capacity : 容量,表示緩衝區中最大儲存資料的容量。一旦宣告不能改變。
limit : 界限,表示緩衝區中可以運算元據的大小。(limit 後資料不能進行讀寫)
position : 位置,表示緩衝區中正在運算元據的位置。

mark : 標記,表示記錄當前 position 的位置。可以通過 reset() 恢復到 mark 的位置

0 <= mark <= position <= limit <= capacity

 使用demo:

package com.soyoungboy.nio;

import java.nio.ByteBuffer;

import org.junit.Test;
/**
 * 緩衝區
 * @author soyoungboy
 *
 */
public class TestBuffer {
    
    @Test
    public void test3(){
        //分配直接緩衝區
        ByteBuffer buf = ByteBuffer.allocateDirect(1024);
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());
        System.out.println(buf.isDirect());
    }
    
    @Test
    public void test2(){
        String str = "abcde";
        
        ByteBuffer buf = ByteBuffer.allocate(1024);
        
        buf.put(str.getBytes());
        
        buf.flip();
        
        byte[] dst = new byte[buf.limit()];
        buf.get(dst, 0, 2);
        System.out.println(new String(dst, 0, 2));
        System.out.println(buf.position());
        
        //mark() : 標記
        buf.mark();
        
        buf.get(dst, 2, 2);
        System.out.println(new String(dst, 2, 2));
        System.out.println(buf.position());
        
        //reset() : 恢復到 mark 的位置
        buf.reset();
        System.out.println(buf.position());
        
        //判斷緩衝區中是否還有剩餘資料
        if(buf.hasRemaining()){
            
            //獲取緩衝區中可以操作的數量
            System.out.println(buf.remaining());
        }
    }
    
    @Test
    public void test1(){
        String str = "abcde";
        
        //1. 分配一個指定大小的緩衝區
        ByteBuffer buf = ByteBuffer.allocate(1024);
        
        System.out.println("-----------------allocate()----------------");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());
        
        //2. 利用 put() 存入資料到緩衝區中
        buf.put(str.getBytes());
        
        System.out.println("-----------------put()----------------");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());
        
        //3. 切換讀取資料模式
        buf.flip();
        
        System.out.println("-----------------flip()----------------");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());
        
        //4. 利用 get() 讀取緩衝區中的資料
        byte[] dst = new byte[buf.limit()];
        buf.get(dst);
        System.out.println(new String(dst, 0, dst.length));
        
        System.out.println("-----------------get()----------------");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());
        
        //5. rewind() : 可重複讀
        buf.rewind();
        
        System.out.println("-----------------rewind()----------------");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());
        
        //6. clear() : 清空緩衝區. 但是緩衝區中的資料依然存在,但是處於“被遺忘”狀態
        buf.clear();
        
        System.out.println("-----------------clear()----------------");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());
        
        System.out.println((char)buf.get());
        
    }

}

 

相關文章