Java NIO (New I/O) 自 JDK 1.4 引入,NIO.2 (JDK 7) 進一步強化。本文精選五大實用功能,附完整程式碼與操作說明。
取代傳統輪詢,使用 WatchService 即時偵測目錄建立、刪除、修改事件。
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.*;
public class DirWatcher {
public static void main(String[] args) throws Exception {
Path dir = Paths.get(".");
WatchService watcher = dir.getFileSystem().newWatchService();
dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
System.out.println("正在監聽當前目錄...");
WatchKey key = watcher.take(); // 阻塞直到有事件
for (WatchEvent> ev : key.pollEvents()) {
System.out.println("偵測到:" + ev.kind() + " -> " + ev.context());
}
}
}
單執行緒同時處理多個 Socket 通道,適合高併發網路伺服器。
// 核心邏輯片段
Selector selector = Selector.open();
for (int port : ports) {
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
ssc.socket().bind(new InetSocketAddress(port));
ssc.register(selector, SelectionKey.OP_ACCEPT);
}
while (true) {
selector.select();
for (SelectionKey key : selector.selectedKeys()) {
if (key.isAcceptable()) { /* accept 新連線並註冊 OP_READ */ }
if (key.isReadable()) { /* 讀取資料並 echo 回去 */ }
}
selector.selectedKeys().clear();
}
Channel 統一檔案、網路、標準輸出入操作,支援非阻塞與記憶體映射。
FileChannel:檔案隨機存取、鎖定、映射SocketChannel/ServerSocketChannel:網路非阻塞通訊ByteBuffer:資料載體,配合 flip()/compact() 切換讀寫模式將檔案區段直接映射至記憶體,存取速度接近記憶體級,適合大檔案高頻讀寫。
RandomAccessFile raf = new RandomAccessFile("big.dat", "rw");
MappedByteBuffer mbb = raf.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 20_000_000);
for (int i = 0; i < 20_000_000; i++) mbb.put((byte) 'A');
System.out.println("寫入完成,前 30 字元:" + new String(mbb.array(), 0, 30));
比 String.getBytes() 更靈活、效能更好,支援任意字集互轉。
Charset utf8 = StandardCharsets.UTF_8;
Charset big5 = Charset.forName("Big5");
ByteBuffer buf = utf8.encode("測試字串");
CharBuffer cb = big5.decode(buf);
System.out.println("Big5 字元:" + cb);
NIO/NIO.2 提供底層 I/O 控制能力,適用於高效能、高併發場景。掌握 WatchService、Selector、Channel、MappedByteBuffer、Charset 五大核心,即可應對多數進階 I/O 需求。