首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java IO/NIO 入門完整指南:流模型、裝飾者模式、NIO 通道與緩衝區

     編輯:Java 程式設計入門

什麼是 IO?

IO (Input/Output) 是程式與外部 (檔案、網路、主控台、裝置) 交換資料的介面。Java 核心庫提供兩套體系:

  • java.io:流 (Stream) 基礎,串列化讀寫,API 簡單、易用、效率中等
  • java.nio (New IO):塊 (Block) / 通道 基礎,緩衝區、非阻塞、記憶體映射、高效能

Java IO 流模型與裝飾者模式

核心繼承體系


InputStream (抽象)          OutputStream (抽象)
    ↑                             ↑
FileInputStream            FileOutputStream     -- 資料源節點
ByteArrayInputStream       ByteArrayOutputStream
PipedInputStream           PipedOutputStream

FilterInputStream          FilterOutputStream   -- 裝飾者基類
    ↑                             ↑
BufferedInputStream        BufferedOutputStream -- 緩衝裝飾
DataInputStream            DataOutputStream     -- 基本型別讀寫裝飾
ObjectInputStream          ObjectOutputStream   -- 物件序列化裝飾
GZIPInputStream            GZIPOutputStream     -- 壓縮裝飾
CipherInputStream          CipherOutputStream   -- 加密裝飾

裝飾者模式組裝範例


// 需求:帶緩衝的檔案輸入流
InputStream in = new BufferedInputStream(
                    new FileInputStream("C:\\log.txt"));

// 進一步:帶緩衝、可讀基本型別、可讀物件
DataInputStream din = new DataInputStream(
    new BufferedInputStream(
        new FileInputStream("data.bin")));

int i = din.readInt();
String s = din.readUTF();
MyObject obj = (MyObject) new ObjectInputStream(din).readObject();

精髓: 先建立資料源節點流,再層層包裝裝飾流,獲得組合功能。

Reader/Writer 字元流體系

  • 針對文字,自動處理字元編碼轉換 (位元組 ↔ 字元)
  • 對應關係:InputStreamReader / OutputStreamWriter (橋接位元組流與字元流)
  • 常用:BufferedReader (readLine)、PrintWriter (printf/println)、FileReader/Writer

Java NIO 核心三大支柱

1. Channel (通道) — 雙向、非阻塞

2. Buffer (緩衝區) — 容器、狀態機


// 核心屬性
capacity  // 容量 (不可變)
limit     // 邊界 (寫模式=capacity,讀模式=寫入資料量)
position  // 當前游標
mark      // 標記位置 (reset() 回歸)

// 關鍵操作
put()   // 寫入,position++
get()   // 讀取,position++
flip()  // 寫→讀:limit=position, position=0
rewind()// 重讀:position=0
clear() // 重寫:position=0, limit=capacity
compact()// 未讀資料前移,準備繼續寫入

3. Selector (選擇器) — 多路複用核心


Selector selector = Selector.open();
serverChannel.configureBlocking(false);
serverChannel.register(selector, SelectionKey.OP_ACCEPT);

while (true) {
    selector.select(); // 阻塞直到有就緒事件
    Set keys = selector.selectedKeys();
    for (SelectionKey key : keys) {
        if (key.isAcceptable()) { /* accept 新連線 */ }
        if (key.isReadable()) { /* 讀取資料 */ }
        if (key.isWritable()) { /* 寫入資料 */ }
    }
    keys.clear();
}

單一執行緒管理成千上萬連線,解決傳統「一連線一執行緒」擴展性瓶頸。

NIO 進階特性

  • 記憶體映射檔案:FileChannel.map(MapMode.READ_WRITE, 0, size) → MappedByteBuffer,OS 級頁面映射,大檔案極快
  • 檔案鎖:channel.lock()/tryLock(),跨進程同步
  • 零拷貝:channel.transferTo()/transferFrom(),核心態直接傳輸,避免用戶態拷貝
  • 直接緩衝區:ByteBuffer.allocateDirect(),堆外記憶體,減少 GC 壓力,適合網路 IO

IO vs NIO 選型指南

Channel 實作用途
FileChannel檔案讀寫、記憶體映射、檔案鎖
SocketChannelTCP 非阻塞網路通訊
ServerSocketChannel非阻塞伺服器端接受連線
DatagramChannelUDP 非阻塞
Pipe.SinkChannel/SourceChannel執行緒間管道

現代發展:NIO.2 (Java 7+) 與 Reactive Streams

  • java.nio.file:Path, Files, FileVisitor, WatchService (檔案系統事件)
  • AsynchronousFileChannel / AsynchronousSocketChannel:真正非同步 (CompletionHandler / Future)
  • Reactive Streams (Project Reactor, RxJava) / java.util.concurrent.Flow:背壓、組合式非同步
  • Virtual Threads (Java 21+):阻塞式 API 也能達到高併發,重新評估 NIO 必要性

總結

Java IO 以裝飾者模式實現靈活功能組合;NIO 以Channel + Buffer + Selector實現高擴展性非阻塞 IO。理解兩者本質差異,依場景選型。現代開發多由框架 (Netty, Spring WebFlux, gRPC) 封裝 NIO 複雜度,但掌握核心原理對調優、排錯、架構決策不可或缺。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
場景推薦理由
中小檔案、簡單邏輯、工具腳本java.io (BufferedReader/Writer)API 簡潔、開發效率高
高併發網路伺服器 (Web、IM、遊戲)java.nio (Selector + Channel)單執行緒萬連線、低延遲
大檔案處理 (GB 級)NIO MappedByteBuffer / transferToOS 頁面映射、零拷貝
跨進程檔案同步NIO FileLock系統級鎖
Spring Boot / Netty / gRPC 應用NIO (框架封裝)框架屏蔽複雜度