I/O流与I/O框架全面总结

一、Java I/O流基础

1. I/O流分类

按数据流向

  • 输入流:从数据源读取数据(InputStream/Reader)
  • 输出流:向目标写入数据(OutputStream/Writer)

按数据类型

  • 字节流:以字节为单位(8位),处理二进制数据
    • InputStream/OutputStream
  • 字符流:以字符为单位(16位),处理文本数据
    • Reader/Writer

按功能

  • 节点流:直接操作数据源/目标的流
  • 处理流:对现有流进行包装,提供增强功能

2. 核心类体系

字节流体系

text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
InputStream (抽象类)
├─ FileInputStream (文件输入)
├─ ByteArrayInputStream (内存数组输入)
├─ FilterInputStream (装饰器父类)
│ ├─ BufferedInputStream (缓冲流)
│ ├─ DataInputStream (基本数据类型读取)
└─ ObjectInputStream (对象反序列化)

OutputStream (抽象类)
├─ FileOutputStream (文件输出)
├─ ByteArrayOutputStream (内存数组输出)
├─ FilterOutputStream (装饰器父类)
│ ├─ BufferedOutputStream (缓冲流)
│ ├─ DataOutputStream (基本数据类型写入)
└─ ObjectOutputStream (对象序列化)

字符流体系

text

1
2
3
4
5
6
7
8
9
10
11
12
13
Reader (抽象类)
├─ InputStreamReader (字节到字符桥接)
│ └─ FileReader (文件字符输入)
├─ BufferedReader (缓冲字符输入)
├─ CharArrayReader (字符数组输入)
└─ StringReader (字符串输入)

Writer (抽象类)
├─ OutputStreamWriter (字符到字节桥接)
│ └─ FileWriter (文件字符输出)
├─ BufferedWriter (缓冲字符输出)
├─ CharArrayWriter (字符数组输出)
└─ StringWriter (字符串输出)

二、常用I/O流详解

1. 文件操作流

java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 字节流文件复制
try (FileInputStream fis = new FileInputStream("source.txt");
FileOutputStream fos = new FileOutputStream("target.txt")) {
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
}

// 字符流文件读取
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}

2. 缓冲流(提升性能)

java

1
2
3
4
5
6
7
8
9
// 使用缓冲流提升复制效率
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("source.jpg"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("target.jpg"))) {
byte[] buffer = new byte[8192]; // 8KB缓冲区
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
}

3. 对象序列化流

java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 对象序列化
class Person implements Serializable {
private String name;
private transient int age; // transient修饰的字段不会被序列化

// 构造方法、getter/setter...
}

// 序列化对象到文件
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"))) {
oos.writeObject(new Person("张三", 25));
}

// 反序列化
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"))) {
Person p = (Person) ois.readObject();
System.out.println(p.getName());
}

三、NIO(New I/O)

1. NIO核心组件

  • Channel:双向数据传输通道
    • FileChannel
    • SocketChannel
    • ServerSocketChannel
  • Buffer:数据容器
    • ByteBuffer
    • CharBuffer
    • IntBuffer
  • Selector:多路复用器

2. NIO示例

java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 使用FileChannel复制文件
try (FileChannel src = FileChannel.open(Paths.get("source.txt"), StandardOpenOption.READ);
FileChannel dest = FileChannel.open(Paths.get("target.txt"),
StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {
src.transferTo(0, src.size(), dest);
}

// 使用Buffer读写
ByteBuffer buffer = ByteBuffer.allocate(1024);
try (FileChannel channel = FileChannel.open(Paths.get("data.txt"), StandardOpenOption.READ)) {
while (channel.read(buffer) > 0) {
buffer.flip(); // 切换为读模式
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
buffer.clear(); // 清空缓冲区,准备再次写入
}
}

四、常用I/O框架

1. Apache Commons IO

核心功能

  • FileUtils:文件操作工具类
  • IOUtils:流操作工具类
  • FilenameUtils:文件名处理工具

示例代码

java

1
2
3
4
5
6
7
8
9
10
// 复制文件
File srcFile = new File("source.txt");
File destFile = new File("target.txt");
FileUtils.copyFile(srcFile, destFile);

// 读取文件内容为字符串
String content = FileUtils.readFileToString(new File("data.txt"), "UTF-8");

// 逐行读取
List<String> lines = FileUtils.readLines(new File("log.txt"), "UTF-8");

2. Google Guava

核心功能

  • Files:文件操作工具
  • CharStreams/ByteStreams:流工具
  • Resources:资源读取工具

示例代码

java

1
2
3
4
5
6
7
8
9
10
11
// 读取文件所有行
List<String> lines = Files.readLines(new File("data.txt"), Charsets.UTF_8);

// 复制文件
File src = new File("source.jpg");
File dest = new File("target.jpg");
Files.copy(src, dest);

// 读取资源文件
URL url = Resources.getResource("config.properties");
String text = Resources.toString(url, Charsets.UTF_8);

3. Java 7+ Files工具类

java

1
2
3
4
5
6
7
8
9
10
11
12
13
// 读取所有行
List<String> lines = Files.readAllLines(Paths.get("data.txt"));

// 写入文件
Files.write(Paths.get("output.txt"), "Hello World".getBytes());

// 复制文件
Files.copy(Paths.get("source.txt"), Paths.get("target.txt"));

// 遍历目录
Files.walk(Paths.get("/path/to/dir"))
.filter(Files::isRegularFile)
.forEach(System.out::println);

五、性能优化建议

  1. 使用缓冲流:减少物理I/O操作次数
  2. 合理设置缓冲区大小:通常8KB-32KB为宜
  3. 及时关闭资源:使用try-with-resources
  4. NIO处理大文件:对于大文件操作,NIO性能更优
  5. 选择合适流类型:文本数据用字符流,二进制数据用字节流
  6. 批量操作:尽量批量读写而非单字节/字符操作

六、常见应用场景

  1. 文件操作:读写、复制、移动、删除
  2. 网络通信:Socket数据传输
  3. 数据持久化:对象序列化/反序列化
  4. 日志处理:日志文件读写
  5. 配置文件:properties/xml/json等配置读取
  6. 资源加载:类路径资源读取

掌握这些I/O流和框架的知识点,可以显著提升程序性能和开发效率