?
?
0. 介紹
參考? ?關于Java IO與NIO知識都在這里? ?,在其基礎上進行修改與補充。
?
?
1. NIO介紹
1.1 NIO 是什么
Java NIO 是 java 1.4, 之后新出的一套IO接口.
NIO中的N可以理解為Non-blocking,不單純是New。
?
1.2 NIO的特性/NIO與IO區別
- IO是面向流的,NIO是面向緩沖區的。
- IO流是阻塞的,NIO流是不阻塞的。
- NIO有選擇器,而IO沒有。
?
阻塞和非阻塞關注的是程序在等待調用結果(消息,返回值)時的狀態.
阻塞調用:是指調用結果返回之前,當前線程會被掛起。調用線程只有在得到結果之后才會返回。
非阻塞調用:指在不能立刻得到結果之前,該調用不會阻塞當前線程。
1.3 讀數據和寫數據方式
- 從通道進行數據讀取 :創建一個緩沖區,然后請求通道讀取數據。
- 從通道進行數據寫入 :創建一個緩沖區,填充數據,并要求通道寫入數據。
1.4 NIO核心組件簡單介紹
- Channels
- Buffers
- Selectors
?
?
2.?Buffer
2.1 Buffer(緩沖區)介紹
- Java NIO Buffer用于和NIO Channel交互。我們從Channel中讀取數據到Buffer里,從Buffer把數據寫入到Channel;
- Buffer本質上就是一塊內存區;
2.2 Buffer 的屬性
capacity(容量):
緩沖區的 capacity 表明可以儲存在緩沖區中的最大數據容量。實際上,它指定了底層數組的大小 ,或者至少是指定了準許我們使用的底層數組的容量。一旦Buffer寫滿了就需要清空已讀數據以便下次繼續寫入新的數據。
?
position(位置):
當寫入數據到Buffer的時候需要選中一個確定的位置開始,默認初始化時這個位置position為0,一旦寫入了數據比如一個字節,整型數據,那么position的值就會指向數據之后的一個單元,position最大可以到capacity-1。
當從Buffer讀取數據時,也需要從一個確定的位置開始。Buffer從寫入模式變為讀取模式時,position會歸零,每次讀取后,position向后移動。
?
limit(限制):
在寫模式,limit的含義是我們所能寫入的最大數據量。它等同于Buffer的容量。
一旦切換到讀模式,limit則代表我們所能讀取的最大數據量,他的值等同于寫模式下position的位置。
數據讀取的上限是Buffer中已有的數據,也就是limit的位置(原position所指的位置)。
? 2.3 Buffer的常見方法
mark() :
記錄當前標記,以便后來可以定位到此處
0 <= mark <= position <= limit <= capacity
?
? reset():
將position定位到mark處
?
rewind()
取消mark標記
?
flip():
flip()方法可以吧Buffer從寫模式切換到讀模式。調用flip()方法會把position歸零,并設置limit為之前的position的值。 也就是說,現在position代表的是讀取位置,limit標示的是已寫入的數據位置。
?
clear() :
為寫數據做好準備,相當于緩沖區剛分配時的狀態
將limit設置為capacity的值
將position歸零
?
2.4 Buffer的使用方式/方法介紹
分配緩沖區(Allocating a Buffer):
ByteBuffer buf = ByteBuffer.allocate(10);
寫入數據到緩沖區(Writing Data to a Buffer):
方法一:從Channel中寫數據到Buffer
int bytesRead = inChannel.read(buf);
?
方法二:通過put寫數據
buf.put(10);
?
?
3. Channel
3.1 介紹
通常來說NIO中的所有IO都是從 Channel(通道) 開始的。
從通道進行數據讀取 :創建一個緩沖區,然后請求通道讀取數據。
從通道進行數據寫入 :創建一個緩沖區,填充數據,并要求通道寫入數據。
數據讀取和寫入操作圖示:
3.2 channel與流的區別
- 通道可以讀也可以寫,流一般來說是單向的(只能讀或者寫,所以之前我們用流進行IO操作的時候需要分別創建一個輸入流和一個輸出流)。
- 通道可以異步讀寫。
- 通道總是基于緩沖區Buffer來讀寫。
?
3.3 Java NIO中最重要的幾個Channel的實現
- FileChannel: 用于文件的數據讀寫
- DatagramChannel: 用于UDP的數據讀寫
- SocketChannel: 用于TCP的數據讀寫,一般是客戶端實現
- ServerSocketChannel: 允許我們監聽TCP鏈接請求,每個請求會創建會一個SocketChannel,一般是服務器實現
待補充。。。
?
?
4. Selector
4.1 介紹
Selector 一般稱 為選擇器 ,它是Java NIO核心組件中的一個,用于檢查一個或多個NIO Channel(通道)的狀態是否處于可讀、可寫。如此可以實現單線程管理多個channels,也就是可以管理多個網絡鏈接。
使用Selector的好處在于: 使用更少的線程來就可以來處理通道了, 相比使用多個線程,避免了線程上下文切換帶來的開銷。
待補充。。。
?
?
?