Java IO流:核心概念、使用场景与代码示例
Java IO流是处理输入/输出的核心机制,基于装饰器模式设计,支持灵活组合。以下内容结合核心概念、使用场景及真实代码示例,涵盖字节流、字符流、缓冲流等关键组件。
一、Java IO流分类与使用场景
| 分类 | 核心类 | 使用场景 | 特点 |
|---|---|---|---|
| 字节流 | InputStream/OutputStream | 二进制文件(图片、视频、压缩包) | 以字节为单位操作,不处理编码 |
| 字符流 | Reader/Writer | 文本文件(.txt、.csv、日志) | 以字符为单位,自动处理编码(如UTF-8) |
| 缓冲流 | BufferedInputStream等 | 大文件读写、高频I/O操作 | 减少磁盘I/O次数,提升性能 |
| 转换流 | InputStreamReader/OutputStreamWriter | 字节流与字符流的桥梁 | 可指定字符编码(如StandardCharsets.UTF_8) |
| 对象流 | ObjectInputStream/ObjectOutputStream | 序列化对象存储或传输 | 需实现Serializable接口 |
选择原则:
- 二进制数据 → 字节流
- 文本数据 → 字符流(优先用缓冲流包装)
- 跨编码场景 → 转换流
二、核心类使用示例
1. 字节流读写文件(二进制操作)
import java.io.*;
public class ByteStreamDemo {
public static void main(String[] args) {
// 使用try-with-resources自动关闭流(避免内存泄漏)
try (FileInputStream fis = new FileInputStream("input.jpg");
FileOutputStream fos = new FileOutputStream("output.jpg")) {
byte[] buffer = new byte[8192]; // 8KB缓冲区(优化性能)
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead); // 写入读取的字节
}
System.out.println("文件复制完成!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 场景:图片/视频复制
- 优化点:缓冲区设为8192字节(磁盘块大小倍数)减少I/O次数
2. 字符流读写文本(带缓冲)
import java.io.*;
import java.nio.charset.StandardCharsets;
public class CharStreamDemo {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(
new FileInputStream("input.txt"), StandardCharsets.UTF_8)); // 指定UTF-8编码
BufferedWriter writer = new BufferedWriter(
new FileWriter("output.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line); // 逐行读写
writer.newLine(); // 换行符适配操作系统
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 场景:日志文件处理、CSV解析
- 关键点:
BufferedReader加速读取(readLine()效率高)- 指定编码避免乱码(
StandardCharsets.UTF_8)
3. 对象序列化与反序列化
import java.io.*;
class User implements Serializable { // 必须实现Serializable
private String name;
public User(String name) { this.name = name; }
@Override
public String toString() { return "User: " + name; }
}
public class ObjectStreamDemo {
public static void main(String[] args) {
// 序列化对象到文件
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("user.dat"))) {
oos.writeObject(new User("Alice"));
} catch (IOException e) { e.printStackTrace(); }
// 从文件反序列化对象
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("user.dat"))) {
User user = (User) ois.readObject();
System.out.println(user); // 输出: User: Alice
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
- 场景:分布式系统数据传输、缓存存储
三、性能优化与问题解决
大文件处理问题
| 问题 | 解决方案 |
|---|---|
| 内存溢出(OOM) | 分块读取(固定缓冲区) + 流式处理 |
| 读写速度慢 | 使用BufferedInputStream/BufferedOutputStream |
| 字符编码不一致 | 用InputStreamReader显式指定编码 |
优化示例(分块读取10GB文件):
byte[] buffer = new byte[8192]; // 8KB缓冲区 int bytesRead; while ((bytesRead = fis.read(buffer)) != -1) { // 处理每个分块(避免全加载到内存) }
避免资源泄漏
- 必须关闭流!推荐 try-with-resources(Java 7+):
try (InputStream is = new FileInputStream("file")) { // 操作流 } // 自动调用close()
四、Java IO vs. NIO
| 特性 | Java IO | Java NIO |
|---|---|---|
| 数据单位 | 流(Stream) | 块(Buffer) + 通道(Channel) |
| 阻塞模式 | 阻塞I/O(线程等待) | 非阻塞/选择器(Selector) |
| 适用场景 | 低并发、简单文件操作 | 高并发网络应用(如聊天服务器) |
NIO示例场景:需同时处理数千连接的Web服务器。
思维导图


3716

被折叠的 条评论
为什么被折叠?



