Java NIO工作機制簡介
前言
本部落格只簡單介紹NIO的原理實現和基本工作流程
I/O和NIO的本質區別
NIO將填充和提取緩衝區的I/O操作轉移到了作業系統
I/O 以流的方式處理資料,而 NIO 以緩衝區的方式處理資料;IO是阻塞的,NIO是非阻塞的,直到有資料被讀取或者資料完全寫入時,IO執行緒才開始執行操作,而NIO在如何情況都是非阻塞的
通道(Channel)和緩衝區(Buffer)
NIO三個核心物件:通道(Channel)、緩衝區(Buffer)和選擇器(Selector)
緩衝區只暫時儲存資料,通道用於讀取和寫入操作,作用相當於IO流,與IO流不同的是通道是雙向的。
NIO操作中,從通道讀取的資料必須先放在緩衝區中,傳送給通道的資料也先放在緩衝區中。
NIO通道
通道:通道是一個物件,可以通過它讀取和寫入資料,可以理解為是對原I/O包中的流的模擬。
通道和流的區別在於通道是雙向。通道可以用於讀、寫或者同時用於讀寫,而流只有一個方向,即一個流必須是InputStream的子類或者OutputStream的子類。
- FileChannel:從檔案中讀寫資料。
- DatagramChannel:能通過UDP讀寫網路中的資料。
- SocketChannel:能通過TCP讀寫網路中的資料。
- ServerSocketChannel:可以監聽新進來的TCP連線,像Web伺服器那樣。對每一個新進來的連線都會建立一個Socke Channel。
NIO緩衝區
緩衝區:緩衝區實質上是一個數組。最常用的緩衝區型別是ByteBuffer,對應Java的基本型別都有一種緩衝區區
緩衝區型別:
- 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);