前言
本博客只簡單介紹NIO的原理實現和基本工做流程html
I/O和NIO的本質區別
NIO將填充和提取緩衝區的I/O操做轉移到了操做系統java
I/O 以流的方式處理數據,而 NIO 以緩衝區的方式處理數據;IO是阻塞的,NIO是非阻塞的,直到有數據被讀取或者數據徹底寫入時,IO線程纔開始執行操做,而NIO在如何狀況都是非阻塞的數組
通道(Channel)和緩衝區(Buffer)
NIO三個核心對象:通道(Channel)、緩衝區(Buffer)和選擇器(Selector)服務器
緩衝區只暫時儲存數據,通道用於讀取和寫入操做,做用至關於IO流,與IO流不一樣的是通道是雙向的。網絡
NIO操做中,從通道讀取的數據必須先放在緩衝區中,發送給通道的數據也先放在緩衝區中。spa
NIO通道
通道:通道是一個對象,能夠經過它讀取和寫入數據,能夠理解爲是對原I/O包中的流的模擬。操作系統
通道和流的區別在於通道是雙向。通道能夠用於讀、寫或者同時用於讀寫,而流只有一個方向,即一個流必須是InputStream的子類或者OutputStream的子類。線程
- FileChannel:從文件中讀寫數據。
- DatagramChannel:能經過UDP讀寫網絡中的數據。
- SocketChannel:能經過TCP讀寫網絡中的數據。
- ServerSocketChannel:能夠監聽新進來的TCP鏈接,像Web服務器那樣。對每個新進來的鏈接都會建立一個Socke Channel。
NIO緩衝區
緩衝區:緩衝區實質上是一個數組。最經常使用的緩衝區類型是ByteBuffer,對應Java的基本類型都有一種緩衝區區code
緩衝區類型:htm
- ByteBuffer
- CharBuffer
- ShortBuffer
- IntBuffer
- LongBuffer
- FloatBuffer
- DoubleBuffer
NIO選擇器
選擇器(Selector):選擇器用於監聽多個通道的事件。Selector容許單線程處理多個 Channel。也就是說能夠註冊多個通道,使用同一個選擇器,只要開一條線程就能夠執行
NIO讀寫操做
NIO讀取過程:先建立一個緩衝區,通道讀取數據放在這個緩衝區
graph LR Channel-->Buffer
NIO寫入過程:也是先建立一個緩衝區,裏面有儲存數據的話,將這些數據發給管道執行寫入操做
graph LR Buffer-->Channel
文件讀取操做 讀取文件過程:從FileInputStream獲取Channel,建立Buffer,將數據從Channel讀到Buffer中
//從FileInputStream獲取通道 FileInputStream fis = new FileInputStream( "readandshow.txt" ); FileChannel fc = fis.getChannel(); //建立緩衝區 ByteBuffer buffer = ByteBuffer.allocate( 1024 ); //將數據從通道讀到緩衝區 fc.read( buffer );
文件寫入過程
FileOutputStream fout=new FileOutputStream("write.txt"); FileChannel fc=fout.getChannel(); ByteBuffer buffer=ByteBuffer.allocate(1024); for (int i=0; i<data.length; i++) { buffer.put(data[i]); } buffer.flip(); fc.write(buffer);