Java NIO (一)--簡介
阿新 • • 發佈:2018-12-25
一、簡介
Java NIO (New IO)是JDK1.4後引入的新輸入/輸出API,提供基於緩衝區(buffer)的塊寫入/讀取,而以前的I/O是基於流(Stream)的方式,NIO基於塊的IO操作,將最耗時的快取區讀取和填充交由底層作業系統實現,因此速度上要快得多;主要由以下三個核心部分組成:
1.Channel
2. Buffer
3. Selector
二、Channel - 通道
通道可以理解為以前的“流”,資料從通道讀取,也可以向通道寫入資料,是雙向的,但是讀取和寫入都必須是使用Buffer,即讀取資料時,需要從通道讀取到快取區,然後再從緩衝區獲取資料,寫入資料也需要先將資料寫入到快取區,再將緩衝區寫入通道;NIO中主要有以下通道型別:
- FileChannel - 檔案IO
- DatagramChannel - UDP傳輸
- SocketChannel - TCP傳輸
- ServerSocketChannel -TCP傳輸
三、Buffer - 緩衝區
緩衝區可以認為是一個數據容器,可以理解為一個基本資料型別陣列,如位元組陣列等;NIO中任何資料輸入/輸出都是必須經由緩衝區實現,主要有以下緩衝區型別:- ByteBuffer
- CharBuffer
- ShortBuffer
- IntBuffer
- LongBuffer
- FloatBuffer
- DoubleBuffer
- MappedByteBuffer
可以看出以上型別覆蓋Java的全部基本型別,MappedByteBuffer(記憶體對映檔案,後續章節講解)對於每種Buffer都有相同的方法,只有ByteBuffer擁有部分特殊的方法
向Buffer中寫資料
寫資料到Buffer有兩種方式:
· 從Channel寫到Buffer。
· 通過Buffer的put()方法寫到Buffer裡。
從Channel寫到Buffer的例子 :
int bytesRead = inChannel.read(buf); //read into buffer.
通過put方法寫Buffer的例子:
buf.put(127);
從Buffer中讀取資料
從Buffer中讀取資料有兩種方式:
· 從Buffer讀取資料到Channel。
· 使用get()方法從Buffer中讀取資料。
從Buffer讀取資料到Channel的例子:
//read from buffer into channel.
int bytesWritten = inChannel.write(buf);
使用get()方法從Buffer中讀取資料的例子 :
byte aByte = buf.get();
四、Selector - 選擇器
選擇器支援單個執行緒處理多個Channel,將多個Channel註冊到一個選擇器中,選擇器基於事件的方式處理;從選擇器獲取註冊Channel中關注的事件(如讀、寫)並進行資料處理,非常適用於多個數據量不大、讀寫不頻繁的通道,使用單個執行緒來處理;五、NIO簡單(標準)的輸入/輸出
一個簡單(標準)的NIO輸入輸出一般包含如下步驟:
1. 從資料來源獲取通道
2. 分配緩衝區
3. 切換快取區為寫模式
4. 從通道讀取資料寫入緩衝區
5. 切換緩衝區為讀模式
6. 緩衝區資料寫入通道中
7. 關閉資源
例項程式碼如下:
package com.denny.aio.test;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class Test {
public static void main(String[] args) throws IOException {
RandomAccessFile formFile = new RandomAccessFile("src\\a.txt", "rw");
RandomAccessFile toFile = new RandomAccessFile("src\\b.txt", "rw");
//獲取channel
FileChannel fromChannel = formFile.getChannel();
FileChannel toChannel = toFile.getChannel();
// 定義緩衝大小
int bufSize = 1024*4;
// 定義緩衝
ByteBuffer byteBuffer = ByteBuffer.allocate(bufSize);
int len = 0;
// 將資料從源channel寫入到緩衝區
while( (len=fromChannel.read(byteBuffer)) !=-1 ){
//切換到讀模式
byteBuffer.flip();
//讀取緩衝區資料寫到目標channel
toChannel.write(byteBuffer);
// 清空緩衝
byteBuffer.clear();
}
// 釋放資源
toChannel.close();
fromChannel.close();
}
}