NIO(一)概述
Java NIO:NIO概述
以下是本文的目錄大綱:
一.NIO中的幾個基礎概念
二.Channel
三.Buffer
四.Selector
一.NIO中的幾個基礎概念
在NIO中有幾個比較關鍵的概念:Channel(通道),Buffer(緩衝區),Selector(選擇器)。
首先從Channel說起吧,通道,顧名思義,就是通向什麼的道路,為某個提供了渠道。在傳統IO中,我們要讀取一個檔案中的內容,通常是像下面這樣讀取的:
1 2 3 4 5 6 7 8 9 |
|
這裡的InputStream實際上就是為讀取檔案提供一個通道的。
因此可以將NIO 中的Channel同傳統IO中的Stream來類比,但是要注意,傳統IO中,Stream是單向的,比如InputStream只能進行讀取操作,OutputStream只能進行寫操作。而Channel是雙向的,既可用來進行讀操作,又可用來進行寫操作。
Buffer(緩衝區),是NIO中非常重要的一個東西,在NIO中所有資料的讀和寫都離不開Buffer。比如上面的一段程式碼中,讀取的資料時放在byte陣列當中,而在NIO中,讀取的資料只能放在Buffer中。同樣地,寫入資料也是先寫入到Buffer中。
下面介紹一下NIO中最核心的一個東西:Selector。可以說它是NIO中最關鍵的一個部分,Selector的作用就是用來輪詢每個註冊的Channel,一旦發現Channel有註冊的事件發生,便獲取事件然後進行處理。
比如看下面的這個例子:
用單執行緒處理一個Selector,然後通過Selector.select()方法來獲取到達事件,在獲取了到達事件之後,就可以逐個地對這些事件進行響應處理。
二.Channel
在前面已經提到,Channel和傳統IO中的Stream很相似。雖然很相似,但是有很大的區別,主要區別為:通道是雙向的,通過一個Channel既可以進行讀,也可以進行寫;而Stream只能進行單向操作,通過一個Stream只能進行讀或者寫;
以下是常用的幾種通道:
- FileChannel
- SocketChanel
- ServerSocketChannel
- DatagramChannel
通過使用FileChannel可以從檔案讀或者向檔案寫入資料;通過SocketChannel,以TCP來向網路連線的兩端讀寫資料;通過ServerSocketChanel能夠監聽客戶端發起的TCP連線,併為每個TCP連線建立一個新的SocketChannel來進行資料讀寫;通過DatagramChannel,以UDP協議來向網路連線的兩端讀寫資料。
下面給出通過FileChannel來向檔案中寫入資料的一個例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
通過上面的程式會向工程目錄下的data.txt檔案寫入字串"java nio",注意在呼叫channel的write方法之前必須呼叫buffer的flip方法,否則無法正確寫入內容,至於具體原因將在下篇博文中具體講述Buffer的用法時闡述。
三.Buffer
Buffer,故名思意,緩衝區,實際上是一個容器,是一個連續陣列。Channel提供從檔案、網路讀取資料的渠道,但是讀取或寫入的資料都必須經由Buffer。具體看下面這張圖就理解了:
上面的圖描述了從一個客戶端向服務端傳送資料,然後服務端接收資料的過程。客戶端傳送資料時,必須先將資料存入Buffer中,然後將Buffer中的內容寫入通道。服務端這邊接收資料必須通過Channel將資料讀入到Buffer中,然後再從Buffer中取出資料來處理。
在NIO中,Buffer是一個頂層父類,它是一個抽象類,常用的Buffer的子類有:
- ByteBuffer
- IntBuffer
- CharBuffer
- LongBuffer
- DoubleBuffer
- FloatBuffer
- ShortBuffer
如果是對於檔案讀寫,上面幾種Buffer都可能會用到。但是對於網路讀寫來說,用的最多的是ByteBuffer。
關於Buffer的具體使用以及它的limit、posiion和capacity這幾個屬性的理解在下一篇文章中講述。
四.Selector
Selector類是NIO的核心類,Selector能夠檢測多個註冊的通道上是否有事件發生,如果有事件發生,便獲取事件然後針對每個事件進行相應的響應處理。這樣一來,只是用一個單執行緒就可以管理多個通道,也就是管理多個連線。這樣使得只有在連線真正有讀寫事件發生時,才會呼叫函式來進行讀寫,就大大地減少了系統開銷,並且不必為每個連線都建立一個執行緒,不用去維護多個執行緒,並且避免了多執行緒之間的上下文切換導致的開銷。
與Selector有關的一個關鍵類是SelectionKey,一個SelectionKey表示一個到達的事件,這2個類構成了服務端處理業務的關鍵邏輯。
關於Selector類的具體使用將在後續文章中闡述。
相關文章
- 【譯】Java NIO 簡明教程系列之 NIO 概述Java
- Netty原始碼分析--NIO(一)Netty原始碼
- NIO的介紹和JDK7下NIO的一個案例JDK
- BIO到NIO原始碼的一些事兒之NIO 上原始碼
- BIO到NIO原始碼的一些事兒之NIO 中原始碼
- Java NIO學習系列一:BufferJava
- NIO
- BIO到NIO原始碼的一些事兒之NIO 下 之 Selector原始碼
- JAVA NIO程式設計入門(一)Java程式設計
- 【死磕NIO】— NIO基礎詳解
- From BIO to NIO —— NIO source code interpretation 1
- Web Components系列(一) —— 概述Web
- ACE之(一)ACE概述
- JavaScript基礎(一)概述JavaScript
- BIO到NIO原始碼的一些事兒之NIO 下 Buffer解讀 上原始碼
- BIO到NIO原始碼的一些事兒之NIO 下 Buffer解讀 下原始碼
- NIO模型模型
- Java NIOJava
- 深入學習Netty(一)NIO基礎篇Netty
- 一文理解:Java NIO 核心元件Java元件
- 網路程式設計NIO:BIO和NIO程式設計
- 數倉(一)數倉概述
- SAP Marketing Cloud 功能概述(一)Cloud
- 行動通訊概述(一)
- Spring Framework5.0.7【一】- 概述SpringFramework
- NIO基礎
- NIO、BIO、Selector
- Java NIO filesJava
- Java NIO - BufferJava
- Java NIO - 群聊Java
- Java NIO:通道Java
- Netty - 眼熟NIONetty
- BIO、NIO、AIOAI
- JAVA NIO BufferJava
- JAVA 探究NIOJava
- Java NIO SocketChannelJava
- Java NIO學習系列四:NIO和IO對比Java
- 【譯】Java NIO 簡明教程系列之 NIO 簡介Java