- Java文件编程
- 传统IO
- NIO
- NIO.2
- 总结
Java文件编程
传统IO
传统IO (java.io包)的主要类:
- FileInputStream/FileOutputStream - 字节流
- FileReader/FileWriter - 字符流
- BufferedReader/BufferedWriter - 缓冲流
- File - 文件/目录操作
文件读取和写入:
- 字节流:File + FileInputStream/FileOutputStream + byte[]
- FileInputStream/FileOutputStream构造函数创建时可以传入File 和String
- 字符流:File + FileReader/FileWriter + BufferedReader/BufferedWriter
- FileReader/FileWriter构造函数创建时可以传入File 和String
- File:File对象作为参数传递给流构造函数。负责文件/目录的创建、删除、重命名、属性查询等管理操作。
优点:
-
简单易用,学习曲线平缓
-
广泛的兼容性,所有Java版本都支持
-
适合简单的文件操作场景
-
明确的异常处理(IOException)
缺点:
- 阻塞IO模型,性能较低
- 缺乏高级功能(如文件锁、内存映射等)
- 缓冲区管理需要手动处理
- 目录遍历功能较弱
NIO
NIO提供了更现代、更高效的文件操作方式,特别适合处理大文件和高并发场景。
NIO (java.nio包Jdk 1.4)的主要类:
- FileChannel - 文件通道
- ByteBuffer - 缓冲区
- Charset - 字符编码处理
文件读取和写入:
- 使用FileChannel进行高性能读写
- FileChannel基础操作:FileChannel + ByteBuffer + 文件(可以是String传递路径、也可以是NIO.2的Files + Paths + Path)
- 内存映射文件(Memory Mapped Files):FileChannel + MappedByteBuffer + 文件(可以是String传递路径、也可以是NIO.2的Files + Paths + Path)
优点:
-
非阻塞IO(对于网络IO),文件IO使用更高效的通道
-
内存映射文件,提高大文件读写性能。MappedByteBuffer
-
文件锁机制
- FileLock lock = channel.lock(); // 获取文件锁
-
聚集写入(Gathering Write)
channel.write(buffer数组);
-
分散读取(Scattering Read)
channel.read(buffer数组);
缺点:
-
API相对复杂,学习曲线较陡
Path path = Paths.get("file.txt");
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class); -
某些操作异常信息不够明确
-
缓冲区管理需要更多关注
-
对于简单操作可能显得繁琐
NIO.2
NIO.2提供了现代化、功能丰富的文件操作API,是当前Java文件处理的首选方案。
NIO.2 不是取代 NIO,而是在 NIO 基础上的增强,两者可以协同工作。
NIO.2 (Java 7+)的主要增强:
- Files - 工具类,提供静态方法
- Paths - 路径操作
- Path - 路径表示
- WatchService - 文件系统监视
- FileVisitor - 目录遍历接口
- FileSystem - 文件系统操作
文件读取和写入:
- 使用Files类进行读写
- 字符读写:Files + Paths + Path + List
- 字节读写:Files + Paths + Path + byte[]
- 字符读写:Files + Paths + Path + List
- 使用BufferedReader/BufferedWriter(NIO版本)
- BufferedReader/BufferedWriter:Files + Paths + Path + BufferedReader/BufferedWriter
- 与NIO协同工作:Files + Paths + Path + FileChannel + ByteBuffer
优点:
- 更强大的Files工具类
Listlines = Files.readAllLines(Paths.get("file.txt"));
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); - 更好的目录遍历支持
try (Streampaths = Files.walk(Paths.get("dir"))) {
paths.filter(Files::isRegularFile)
.forEach(System.out::println);
}
缺点:
- 学习曲线较陡,概念复杂,API庞大
- 内存使用问题:大文件读取的内存压力
- 性能开销:小文件操作可能更慢
总结
- 简单性优先:传统IO(适合初学者、简单场景)
- 性能优先:NIO Channel(适合大文件、高性能需求)
- 功能优先:NIO.2 Files类(适合现代应用开发)
- 兼容性考虑:根据项目环境和团队技能选择
特性 | 传统IO (java.io) | NIO (java.nio) | NIO.2 (java.nio.file) |
---|---|---|---|
引入版本 | Java 1.0 | Java 1.4 | Java 7 |
编程模型 | 阻塞IO | 非阻塞IO + 选择器 | 异步IO + 完整文件系统API |
核心概念 | 流(Stream) | 通道(Channel) + 缓冲区(Buffer) | Path + Files工具类 |
性能 | 一般 | 较高 | 最高 |
易用性 | 简单 | 复杂 | 简单(高级API) |
功能完整性 | 基础 | 中等 | 完整 |
根据需求选择技术:
需求场景 | 推荐技术 | 理由 |
---|---|---|
简单文本读写 | NIO.2的Files类 | 代码简洁,功能完善 |
大文件处理 | NIO的FileChannel | 高性能,内存映射支持 |
二进制文件 | NIO的ByteBuffer | 精确控制,性能优秀 |
目录遍历 | NIO.2的Files.walk() | 功能强大,使用简单 |
文件监视 | NIO.2的WatchService | 传统IO不支持此功能 |
网络编程 | NIO的Selector | 非阻塞IO,高并发 |
兼容老系统 | 传统IO | 最大兼容性 |
简单总结
- 传统IO:适合简单场景、老项目维护、学习基础概念
- NIO:适合高性能需求、大文件处理、网络编程
- NIO.2:适合新项目开发、复杂文件操作、现代API需求
现代Java开发推荐优先使用NIO.2,它在易用性、功能和性能之间取得了最佳平衡。只有在特定性能需求或兼容性要求时,才考虑使用传统IO或基础NIO。