流的分類體系
| 維度 | 分類 | 基類/接口 | 典型實現 | 處理單位 |
| 按方向 | 輸入流 | InputStream / Reader | FileInputStream, FileReader | 數據流向程序 |
| 輸出流 | OutputStream / Writer | FileOutputStream, FileWriter |
| 按數據單位 | 字節流 | InputStream / OutputStream | FileInputStream, ByteArrayOutputStream | 字節 (byte/8bit) |
| 字符流 | Reader / Writer | FileReader, StringWriter | 字符 (char/16bit) |
| 按功能 | 節點流/處理流 | - | BufferedInputStream, DataOutputStream | 裝飾器模式增強 |
核心代碼實戰
1. 字節流複製文件 (圖片/視頻等二進制)
public static void copyByByteStream(File src, File dest) throws IOException {
try (FileInputStream in = new FileInputStream(src);
FileOutputStream out = new FileOutputStream(dest)) {
byte[] buffer = new byte[8192];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
}
}
2. 字符流處理文本文件
public static void writeText(File file, String content, boolean append) throws IOException {
try (FileWriter writer = new FileWriter(file, append)) {
writer.write(content);
}
}
public static String readText(File file) throws IOException {
StringBuilder sb = new StringBuilder();
try (FileReader reader = new FileReader(file)) {
char[] buffer = new char[1024];
int len;
while ((len = reader.read(buffer)) != -1) {
sb.append(buffer, 0, len);
}
}
return sb.toString();
}
3. 緩衝流大幅提升性能 (必用)
// 寫入
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
bw.write("高效寫入");
bw.newLine(); // 跨平台換行
}
// 讀取逐行
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
process(line);
}
}
4. Scanner 靈活解析 (推薦文本讀取)
public static void parseWithScanner(File file) throws FileNotFoundException {
try (Scanner scanner = new Scanner(file, StandardCharsets.UTF_8.name())) {
// 按行讀取
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
}
// 按正則分隔符解析
scanner.useDelimiter("\\s*,\\s*");
while (scanner.hasNext()) {
String token = scanner.next();
}
}
}
轉換流:字節與字符橋梁
// 字節流 → 字符流 (指定編碼)
Reader reader = new InputStreamReader(inputStream, "UTF-8");
Writer writer = new OutputStreamWriter(outputStream, "GBK");
// 實際應用:網絡流轉字符處理
try (BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8))) {
String response = br.readLine();
}
特殊流應用場景
| 流類型 | 用途 | 示例 |
| DataInputStream/DataOutputStream | 基本類型序列化 | writeInt(), readDouble() |
| ObjectInputStream/ObjectOutputStream | 對象序列化 | 實現 Serializable 接口 |
| PrintWriter/PrintStream | 格式化輸出 | printf(), println() |
| ByteArrayInputStream/ByteArrayOutputStream | 內存緩衝操作 | toByteArray(), toString() |
| PipedInputStream/PipedOutputStream | 線程間管道通信 | 生產者-消費者模型 |
| SequenceInputStream | 合併多個輸入流 | 合併多個文件 |
NIO.2 現代文件操作 (JDK 7+)
// 文件讀寫
List<String> lines = Files.readAllLines(Paths.get("file.txt"), StandardCharsets.UTF_8);
Files.write(Paths.get("out.txt"), lines, StandardCharsets.UTF_8, StandardOpenOption.CREATE);
// 大文件流式處理
try (Stream<String> stream = Files.lines(Paths.get("big.log"))) {
stream.filter(l -> l.contains("ERROR")).forEach(System.out::println);
}
// 文件屬性操作
Path path = Paths.get("data.txt");
Files.getLastModifiedTime(path);
Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rw-r--r--"));
最佳實踐總結
- 二進制文件:字節流 + 緩衝 (BufferedInputStream/OutputStream)
- 文本文件:字符流 + 緩衝 (BufferedReader/Writer) 或 Scanner
- 必須指定編碼:構造 InputStreamReader/OutputStreamWriter 時顯式傳 charset
- try-with-resources:自動關閉,防止洩漏
- 大文件流式處理:避免一次性讀入內存,使用 Files.lines() 或 BufferedReader 循環
- 性能關鍵:緩衝區大小 8KB-64KB,減少系統調用
總結
Java IO 體系雖龐大,但掌握「字節/字符、輸入/輸出、節點/處理」三個維度分類,熟練使用緩衝流、轉換流、Scanner、NIO.2,即可應對 95% 文件與網絡數據處理場景。現代開發優先選擇 NIO.2 API,代碼更簡潔、功能更強大、異常處理更規範。