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

Java IO 流全體系詳解:從 File 到 NIO.2 的輸入輸出進化史

     編輯:Java 綜合教學

Java IO 流全體系詳解:從 File 到 NIO.2 的輸入輸出進化史

Java IO 是程序與外部世界 (文件、網絡、設備) 交互的橋樑。本文按**流向**、**數據單位**、**功能角色**三個維度,系統梳理 java.io 包核心類體系、關鍵 API、典型用法、裝飾者模式精髓,並對比 NIO.2 現代化 API。

一、核心抽象:四大基類

抽象基類流向數據單位核心子類代表
InputStream輸入 (讀)字節 (byte)FileInputStream、ByteArrayInputStream、DataInputStream
OutputStream輸出 (寫)字節 (byte)FileOutputStream、ByteArrayOutputStream、DataOutputStream
Reader輸入 (讀)字符 (char, UTF-16)FileReader、BufferedReader、InputStreamReader
Writer輸出 (寫)字符 (char, UTF-16)FileWriter、BufferedWriter、OutputStreamWriter

字節流 處理二進制數據 (圖片、視頻、序列化對象);字符流 專為文本設計,內部自動處理編碼轉換,**中文場景首選字符流避免亂碼**。

二、File 類:文件與目錄的元數據操作

File **不屬於流體系**,僅封裝路徑元數據 (不讀寫內容)。

2.1 構造方法

new File(String pathname);
new File(File parent, String child);
new File(String parent, String child);
new File(URI uri);

2.2 高頻 API 速查

方法返回值說明
exists()boolean路徑是否存在
isFile() / isDirectory()boolean文件/目錄判斷
getAbsolutePath()String絕對路徑
getName()String文件名
length()long文件大小 (字節)
lastModified()long最後修改時間戳
list() / listFiles()String[] / File[]列出子項 (可配合 FilenameFilter/FileFilter 過濾)
mkdir() / mkdirs()boolean創建目錄 (單級/多級)
createNewFile()boolean創建空文件 (原子操作)
delete()boolean刪除 (目錄必須為空)
renameTo(File dest)boolean重命名/移動

三、字節流深度解析

3.1 基礎節點流

  • FileInputStream / FileOutputStream:直接操作磁盤文件,**構造方法拋 FileNotFoundException**。
  • ByteArrayInputStream / ByteArrayOutputStream:內存緩衝區作為數據源/目的地,**無需關閉**。

3.2 核心讀寫方法

// InputStream
int read();                    // 讀單字節,返回 0-255 或 -1 (EOF)
int read(byte[] b);            // 批量讀入數組,返回實際讀取字節數
int read(byte[] b, int off, int len); // 指定偏移長度
long skip(long n);             // 跳過 n 字節
int available();               // 剩餘可讀字節數 (不一定準確)
void close();                  // 關閉釋放資源

// OutputStream
void write(int b);             // 寫單字節 (低 8 位)
void write(byte[] b);          // 寫數組
void write(byte[] b, int off, int len);
void flush();                  // 強制刷新緩衝區
void close();                  // 關閉 (含 flush)

3.3 處理流 (裝飾者模式經典應用)

四、字符流深度解析

4.1 橋接流:編碼轉換核心

// 字節流 → 字符流 (解碼)
Reader reader = new InputStreamReader(inputStream, "UTF-8");
// 字符流 → 字節流 (編碼)
Writer writer = new OutputStreamWriter(outputStream, "UTF-8");

FileReader/FileWriter 內部默認使用平台默認編碼,生產環境**強制指定 UTF-8** 避免跨平台亂碼。**

4.2 緩衝字符流:逐行讀寫利器

// 讀取
BufferedReader br = new BufferedReader(new FileReader("log.txt", StandardCharsets.UTF_8));
String line;
while ((line = br.readLine()) != null) { /* 處理行 */ }

// 寫入
BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt", StandardCharsets.UTF_8));
bw.write("第一行");
bw.newLine(); // 跨平台換行符
bw.flush();

4.3 打印流:格式化輸出

PrintWriter pw = new PrintWriter(new FileWriter("fmt.txt"), true); // autoFlush
pw.printf("用戶:%s, 年齡:%d%n", "張三", 25);
pw.println("自動換行");

五、RandomAccessFile:隨機訪問獨行俠

  • **不繼承四大基類**,直接實現 DataInput/DataOutput,可讀可寫、可隨機定位**。
  • 構造:new RandomAccessFile(file, "rw") (模式:r 唯讀、rw 讀寫)。
  • 核心方法:seek(long pos) 移動指針、getFilePointer() 獲取位置、length() 文件長度。
  • 適用場景:大文件斷點續傳、隨機修改文件中間數據、簡易索引實現。

六、裝飾者模式在 IO 體系的淋漓盡致

// 核心思想:動態組合功能,而非繼承爆炸
InputStream in = new FileInputStream("data.bin");
in = new BufferedInputStream(in);      // 加緩衝
in = new DataInputStream(in);          // 加類型化讀取
in = new GZIPInputStream(in);          // 加解壓
// 讀取邏輯完全針對 DataInputStream 接口編程
int value = in.readInt();

優勢: 單一職責、靈活組合、開閉原則。
缺點: 對象層層包裹,調試堆疊深、創建對象多。

七、NIO.2 (Java 7+) 現代化文件 API — 徹底告別 File 類

處理流被裝飾流增強功能典型組合
BufferedInputStream/BufferedOutputStream任意 InputStream/OutputStream**緩衝區 (默認 8KB)**,大幅減少系統調用,IO 性能倍增器new BufferedInputStream(new FileInputStream("a.dat"))
DataInputStream/DataOutputStream任意 InputStream/OutputStream按基本類型讀寫 (readInt()/writeInt() 等),**跨平台二進制格式**網絡協議、對象序列化
ObjectInputStream/ObjectOutputStream任意 InputStream/OutputStream對象序列化/反序列化 (Serializable)RPC、分布式會話
GZIPInputStream/GZIPOutputStream任意 InputStream/OutputStream流式壓縮/解壓HTTP 壓縮傳輸
舊 API (java.io)新 API (java.nio.file)優勢
new File(path)Paths.get(path) / Path不可變、線程安全、豐富路徑操作
file.listFiles()Files.list(dir) / Files.walk(dir)流式、惰性、支援並行流
file.renameTo()Files.move(src, target, REPLACE_EXISTING)原子移動、跨文件系統、異常信息豐富
手動讀寫流Files.readAllLines()/Files.write()/Files.newBufferedReader()一行代碼搞定、自動資源管理
無Files.walkFileTree()訪問者模式遞歸、完整異常控制
無WatchService文件系統事件監聽 (熱加載、同步)

八、最佳實踐清單

  1. 文本文件: Files.newBufferedReader(path, StandardCharsets.UTF_8) + try-with-resources。
  2. 二進制文件: Files.newInputStream(path) + BufferedInputStream。
  3. 大文件拷貝: Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING) (底層零拷貝 sendfile)。
  4. 配置文件讀取: getClass().getResourceAsStream("/config.properties") (ClassPath 資源)。
  5. 序列化: 實現 Serializable、聲明 serialVersionUID、慎用 transient。
  6. 資源關閉: **永遠使用 try (Resource r = ...) { }**,JDK 9+ 可 try (var in = Files.newInputStream(p)) { }。

九、總結

Java IO 從 File 元數據操作、四大流體系、裝飾者模式靈活組合,演進至 NIO.2 Path/Files/WatchService 現代化 API。**核心不變:流是有序數據序列,裝飾者賦能,編碼轉換是字符流靈魂**。選對工具 (NIO.2 為主、舊 IO 為輔),寫出健壯、高性能、跨平台的 IO 代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved