Java:全面 & 清晰的 NIO 學習攻略
阿新 • • 發佈:2018-12-22
前言
JDK 1.4
後,Java
提供了一個全新的IO API
,即Java New IO
- 本文 全面 & 詳細解析
Java New IO
,希望你們會喜歡
目錄
儲備知識:Java IO
1. 定義
- 即
Java New IO
- 是1個全新的、
JDK 1.4
後提供的IO API
2. 作用
- 提供了與標準
IO
不同的IO
工作方式 - 可替代 標準
Java IO
的IO API
3. 新特性
對比於 Java IO
,NIO
具備的新特性如下
4. 核心元件
Java NIO
的核心元件 包括:
- 通道(
Channel
) - 緩衝區(
Buffer
) - 選擇器(
Selectors
下面將詳細介紹:
5. 具體使用
5.1 基於通道 & 緩衝資料
具體步驟如下:
// 1. 獲取資料來源 和 目標傳輸地的輸入輸出流(此處以資料來源 = 檔案為例) FileInputStream fin = new FileInputStream(infile); FileOutputStream fout = new FileOutputStream(outfile); // 2. 獲取資料來源的輸入輸出通道 FileChannel fcin = fin.getChannel(); FileChannel fcout = fout.getChannel(); // 3. 建立 緩衝區 物件:Buffer(共有2種方法) // 方法1:使用allocate()靜態方法 ByteBuffer buff = ByteBuffer.allocate(256); // 上述方法建立1個容量為256位元組的ByteBuffer // 注:若發現建立的緩衝區容量太小,則重新建立一個大小合適的緩衝區 // 方法2:通過包裝一個已有的陣列來建立 // 注:通過包裝的方法建立的緩衝區保留了被包裝陣列內儲存的資料 ByteBuffer buff = ByteBuffer.wrap(byteArray); // 額外:若需將1個字串存入ByteBuffer,則如下 String sendString="你好,伺服器. "; ByteBuffer sendBuff = ByteBuffer.wrap(sendString.getBytes("UTF-16")); // 4. 從通道讀取資料 & 寫入到緩衝區 // 注:若 以讀取到該通道資料的末尾,則返回-1 fcin.read(buff); // 5. 傳出資料準備:將快取區的寫模式 轉換->> 讀模式 buff.flip(); // 6. 從 Buffer 中讀取資料 & 傳出資料到通道 fcout.write(buff); // 7. 重置緩衝區 // 目的:重用現在的緩衝區,即 不必為了每次讀寫都建立新的緩衝區,在再次讀取之前要重置緩衝區 // 注:不會改變緩衝區的資料,只是重置緩衝區的主要索引值 buff.clear();
5.2 基於選擇器(Selecter)
具體步驟如下:
// 1. 建立Selector物件 Selector sel = Selector.open(); // 2. 向Selector物件繫結通道 // a. 建立可選擇通道,並配置為非阻塞模式 ServerSocketChannel server = ServerSocketChannel.open(); server.configureBlocking(false); // b. 繫結通道到指定埠 ServerSocket socket = server.socket(); InetSocketAddress address = new InetSocketAddress(port); socket.bind(address); // c. 向Selector中註冊感興趣的事件 server.register(sel, SelectionKey.OP_ACCEPT); return sel; // 3. 處理事件 try { while(true) { // 該呼叫會阻塞,直到至少有一個事件就緒、準備發生 selector.select(); // 一旦上述方法返回,執行緒就可以處理這些事件 Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> iter = keys.iterator(); while (iter.hasNext()) { SelectionKey key = (SelectionKey) iter.next(); iter.remove(); process(key); } } } catch (IOException e) { e.printStackTrace(); }
6. 例項講解
- 例項說明:實現檔案複製功能
- 實現方式:通道
FileChannel
、 緩衝區ByteBuffer
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class Test {
public static void main(String[] args) throws IOException {
// 設定輸入源 & 輸出地 = 檔案
String infile = "C:\\copy.sql";
String outfile = "C:\\copy.txt";
// 1. 獲取資料來源 和 目標傳輸地的輸入輸出流(此處以資料來源 = 檔案為例)
FileInputStream fin = new FileInputStream(infile);
FileOutputStream fout = new FileOutputStream(outfile);
// 2. 獲取資料來源的輸入輸出通道
FileChannel fcin = fin.getChannel();
FileChannel fcout = fout.getChannel();
// 3. 建立緩衝區物件
ByteBuffer buff = ByteBuffer.allocate(1024);
while (true) {
// 4. 從通道讀取資料 & 寫入到緩衝區
// 注:若 以讀取到該通道資料的末尾,則返回-1
int r = fcin.read(buff);
if (r == -1) {
break;
}
// 5. 傳出資料準備:呼叫flip()方法
buff.flip();
// 6. 從 Buffer 中讀取資料 & 傳出資料到通道
fcout.write(buff);
// 7. 重置緩衝區
buff.clear();
}
}
}
7. 與Java IO的區別
8. 總結
- 本文全面講解了
Java
中的NIO
的相關知識 - 下面我將繼續對
Android & Java
中的知識進行深入講解 ,有興趣可以繼續關注Carson_Ho的安卓開發筆記