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

Java NIO 文件讀寫提速(一):Channel 與 Buffer 協作原理水煙袋模型圖解

     編輯:Java 相關知識

系列首篇,用水煙袋生動類比 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);
    }
}

關鍵步驟註解

  1. buffer.clear():重置寫入位置,不清零數據。
  2. inChannel.read(byteBuf):將文件數據讀入 Buffer,返回讀取位元組數,-1 表 EOF。
  3. byteBuf.flip():必須切換到讀模式,否則 write 寫入 0 位元組。
  4. 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/OutputStreamWriterCharsetDecoder/Encoder

系列導航

  1. 第一篇(本文):Channel/Buffer 協作模型、水煙袋類比、文件備份代碼、零拷貝介紹。
  2. 第二篇:Buffer 內部機制、position/limit/capacity、clear/flip/rewind/compact 狀態機圖解。
  3. 第三篇(規劃):Selector 非阻塞網路編程、多路複用、Netty 入門。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved