I/O流与I/O框架全面总结
一、Java I/O流基础
1. I/O流分类
按数据流向
- 输入流:从数据源读取数据(InputStream/Reader)
- 输出流:向目标写入数据(OutputStream/Writer)
按数据类型
- 字节流:以字节为单位(8位),处理二进制数据
- 字符流:以字符为单位(16位),处理文本数据
按功能
- 节点流:直接操作数据源/目标的流
- 处理流:对现有流进行包装,提供增强功能
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);
|
五、性能优化建议
- 使用缓冲流:减少物理I/O操作次数
- 合理设置缓冲区大小:通常8KB-32KB为宜
- 及时关闭资源:使用try-with-resources
- NIO处理大文件:对于大文件操作,NIO性能更优
- 选择合适流类型:文本数据用字符流,二进制数据用字节流
- 批量操作:尽量批量读写而非单字节/字符操作
六、常见应用场景
- 文件操作:读写、复制、移动、删除
- 网络通信:Socket数据传输
- 数据持久化:对象序列化/反序列化
- 日志处理:日志文件读写
- 配置文件:properties/xml/json等配置读取
- 资源加载:类路径资源读取
掌握这些I/O流和框架的知识点,可以显著提升程序性能和开发效率