NIO v.s. IO
傳統IO:
- 面向流
- 屬於阻塞IO
- 單向管道傳輸:輸入流、輸出流
NIO:
- 面向緩衝區
- 屬於非阻塞IO
- 使用緩衝區在通道內傳輸
緩衝區
緩衝區在NIO中負責數據的存取,緩衝區就是數組,用於存儲不同數據類型的值,除了boolean,都有相應類型的緩衝區。
緩衝區的核心方法:取get()、存put()
4個核心屬性
- capacity:表示緩衝區中最大存儲數據的容量,一旦聲明不能改變。因爲buffer的底層是數組,數據的容量初始化後就不能改變了。
- limit:表示緩衝區中可以操作數據的大小,limit之後的數據不可以進行讀寫。
- position:表示緩衝區正在操作的數據的位置
- mark:記錄當前position的位置,額可以通過reset()恢復到mark的位置
0 <= mark <= position <= limit <= capacity
常用方法:
- rewind():可重複讀
- flip():切換讀模式
- mark():標記
- reset():恢復到mark的位置
- clear():清空緩衝區,但數據依然存在,position、limit、capacity的位置恢復初始狀態
- remain():獲取緩衝區可以操作的數量
直接緩衝區 v.s. 非直接緩衝區
非直接緩衝區:
- 通過allocate()方法分配,將緩衝區建立在JVM的內存中
- 數據傳輸過程:寫入數據時,應用程序寫入用戶地址空間的緩存中,然後拷貝到內核地址空間的緩存中,再寫入物理磁盤。讀取數據時,從物理磁盤讀取到內存地址空間中,再拷貝到用戶地址空間的緩存中,最後讀入程序中。
- 底層是通過創建一個HeapXXXBuffer實現
直接緩衝區:
- 通過allocateDirect()方法分配,將緩衝區建立在物理內存中
- 數據傳輸過程:通過物理內存映射文件直接讀寫
- 底層是通過創建一個DirectXXXBuffer實現
二者比較:各有利弊,直接緩衝區讀寫效率高,但是不安全,內存消耗大。
isDirect()方法可以用來判斷是否是直接緩衝區