系列首篇,用水煙袋生動類比 Channel(管道)與 Buffer(緩衝區)協作原理,零門檻理解 NIO 核心模型,並給出完整文件備份實戰代碼。
水煙袋模型對應關係
| 水煙袋組件 | NIO 組件 | 角色 |
| 煙絲/煙氣 | 數據 (Bytes/Chars) | 流動實體 |
| 煙倉 | 源 Channel (FileChannel.read) | 數據產生端 |
| 水斗 (過濾) | CharsetDecoder/Encoder | 編解碼轉換 |
| 水面空閒區 | Buffer (ByteBuffer/CharBuffer) | 數據暫存/緩衝 |
| 煙管 | 目標 Channel (FileChannel.write) | 數據消費端 |
| 吸氣動作 | Channel.transferTo/transferFrom | 零拷貝傳輸 |
NIO 核心雙元大將
- Channel(管道):雙向、可非阻塞、支援零拷貝、連接實體(文件、Socket、記憶體映射)。
- Buffer(緩衝區):有限容量容器、維護 position/limit/capacity、支援讀寫模式切換。
文件備份完整實戰代碼
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
public class NioFileBackup {
public static void main(String[] args) throws IOException {
String inFile = "C:/wk.txt";
String outFile = "C:/wk-bak.txt";
// 1. 準備:文件流 → Channel
FileInputStream fin = new FileInputStream(inFile);
FileOutputStream fout = new FileOutputStream(outFile);
FileChannel inChannel = fin.getChannel();
FileChannel outChannel = fout.getChannel();
// 2. 緩衝區與編解碼器
ByteBuffer buffer = ByteBuffer.allocate(1024);
Charset charset = Charset.forName("UTF-8");
CharsetDecoder decoder = charset.newDecoder();
CharsetEncoder encoder = charset.newEncoder();
// 3. 核心傳輸循環
while (true) {
buffer.clear(); // 1. 準備寫入:position=0, limit=capacity
CharBuffer charBuf = decoder.decode(buffer); // 解碼(實際讀取在下面)
ByteBuffer byteBuf = encoder.encode(charBuf); // 編碼
int bytesRead = inChannel.read(byteBuf); // 2. 讀入 Channel → Buffer
if (bytesRead == -1) break; // EOF
byteBuf.flip(); // 3. 切換讀模式
outChannel.write(byteBuf); // 4. Buffer → 目標 Channel
}
// 4. 關閉資源
inChannel.close();
outChannel.close();
fin.close();
fout.close();
System.out.println("備份完成: " + outFile);
}
}
關鍵步驟註解
buffer.clear():重置寫入位置,不清零數據。
inChannel.read(byteBuf):將文件數據讀入 Buffer,返回讀取位元組數,-1 表 EOF。
byteBuf.flip():必須切換到讀模式,否則 write 寫入 0 位元組。
outChannel.write(byteBuf):將 Buffer 數據寫入目標文件,position 自動前移。
進階:零拷貝 transferTo(更快)
// 文件到文件直接傳輸,不經用戶態 Buffer,OS 級零拷貝
long transferred = inChannel.transferTo(0, inChannel.size(), outChannel);
適用於文件複製、大文件傳輸,效能遠超 Buffer 循環。
NIO vs 傳統 IO 核心差異
| 維度 | 傳統 IO (BIO) | NIO |
| 流模型 | 單向流 (InputStream/OutputStream) | 雙向 Channel |
| 阻塞模式 | 阻塞 | 可非阻塞 (Selector) |
| 緩衝 | 無 (或自行管理 byte[]) | Buffer 物件管理 |
| 零拷貝 | 不支援 | transferTo/transferFrom |
| 編碼處理 | InputStreamReader/OutputStreamWriter | CharsetDecoder/Encoder |
系列導航
- 第一篇(本文):Channel/Buffer 協作模型、水煙袋類比、文件備份代碼、零拷貝介紹。
- 第二篇:Buffer 內部機制、position/limit/capacity、clear/flip/rewind/compact 狀態機圖解。
- 第三篇(規劃):Selector 非阻塞網路編程、多路複用、Netty 入門。