NIO-1-Java NIO簡介&緩衝區
阿新 • • 發佈:2019-02-16
一、NIO簡介
Java NIO(New IO)是從Java 1.4開始引入的一個新的IO API,可以代替標準的Java IO API。NIO以更加高效的方式進行檔案的讀寫操作。
NIO與IO的區別
IO | NIO |
---|---|
面向流 | 面向快取區 |
阻塞IO(Blocking IO) | 非阻塞IO |
無 | 選擇器 |
二、通道與快取區
- 通道(chanel)
通道表示開啟到IO裝置(檔案、套接字)的連線。 - 緩衝區(Buffer)
一個特定基本資料型別的容器。由java nio包定義的緩衝區都是Buffer類的子類。
Buffer主要與通道進行互動,資料從通道寫入緩衝區,資料從緩衝區中寫入通道。
static XxxBuffer allocate(int capacity) : 建立一個容量為capacity 的XxxBuffer 物件
三、緩衝區
1.緩衝區 :
在 Java NIO 中負責資料的存取。緩衝區就是陣列。用於儲存不同資料型別的資料。
根據資料型別不同(boolean除外),提供了相應型別的緩衝區。
* ByteBuffer
* CharBuffer
* ShortBuffer
* IntBuffer
* LongBuffer
* FloatBuffer
* DoubleBuffer
上述緩衝區的管理方式幾乎一致,通過allocate()獲取緩衝區。
2. 緩衝區存取資料的兩個核心方法
- put():存入資料到緩衝區中。
- get():獲取緩衝區中的資料。
3.緩衝區中的4個核心屬性
- 容量(capacity):表示Buffer最大資料容量,不能為負,建立後不能更改。
- 限制(limit):第一個不應該讀取或寫入的資料索引,即位於limit後的資料不能讀寫。
- 位置(position):寫一個要讀取或寫入的資料的索引。
- 標記(mark)與重置(reset):標記一個指定的索引,之後再通過reset恢復到這個位置。
標記、位置、限制、容量遵守以下不變式:0<=mark<=position<=limit<=capacity
private int mark = -1;
private int position = 0;
private int limit;
private int capacity;
4. Buffer的常用方法
public static void main(String[] args) {
String str = "abcd3";
//1. 分配一個指定大小的緩衝區。
ByteBuffer buf = ByteBuffer.allocate(1024);
System.out.println("-----------allocate--------");
System.out.println("position:" + buf.position());
System.out.println("limit:" + buf.limit());
System.out.println("capacity:" + buf.capacity());
//2.利用put方法存入資料到緩衝區中
buf.put(str.getBytes());//position位置變成了5
System.out.println("position:" + buf.position());//5
System.out.println("-----------put--------");
System.out.println("position:" + buf.position());
System.out.println("limit:" + buf.limit());
System.out.println("capacity:" + buf.capacity());
//3. 呼叫flip()切換到讀資料模式
buf.flip();
System.out.println("-----------flip--------");
System.out.println("position:" + buf.position());//0
System.out.println("limit:" + buf.limit());//5
System.out.println("capacity:" + buf.capacity());//1024
//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("position:" + buf.position());//5
System.out.println("limit:" + buf.limit());//5
System.out.println("capacity:" + buf.capacity());//1024
// 5. rewind():可重複讀資料
buf.rewind();
System.out.println("-----------rewind--------");
System.out.println("position:" + buf.position());//0
System.out.println("limit:" + buf.limit());//5
System.out.println("capacity:" + buf.capacity());//1024
// 6. clear:清空緩衝區,但是緩衝區的資料依然存在,但是處於“被遺忘”狀態
buf.clear();
System.out.println("-----------clear--------");
System.out.println("position:" + buf.position());
System.out.println("limit:" + buf.limit());
System.out.println("capacity:" + buf.capacity());
}
輸出結果:
public void testMark() {
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("position:" + buf.position());//2
//mark : 標記
buf.mark();
System.out.println("-----------remark--------");
buf.get(dst,2,2);
System.out.println("-----------get--------");
System.out.println(new String(dst,2,2));
System.out.println("position:" + buf.position());//4
//reset:恢復到標記位置
buf.reset();
System.out.println("-----------reset--------");
System.out.println("position:" + buf.position());//2
}
輸出結果: