一、使用高效的IO API
- BufferedReader/BufferedWriter 替代普通IO
通过缓冲区减少底层IO调用次数。
// 优化前
FileReader fr = new FileReader("file.txt");
// 优化后
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
- NIO.2(Java 7+)的Path和Files类
提供更简洁的API和性能优化,支持异步IO和文件属性批量操作。
二、减少不必要的IO操作
- 批量读写而非逐字节操作
使用 read(char[]) 或 readLine() 替代逐字节读取,例如:
char[] buffer = new char[8192]; // 8KB缓冲区,避免过小或过大
int len;
while ((len = br.read(buffer)) != -1) {
// 处理批量数据
}
- 避免重复打开/关闭文件
将文件句柄的生命周期拉长,减少频繁打开关闭的开销。
三、合理管理资源
- try-with-resources 自动关闭资源
确保流在使用后及时关闭,避免资源泄漏:
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
// 处理逻辑
} catch (IOException e) {
// 异常处理
}
- 使用内存映射文件(MappedByteBuffer)
适合大文件处理,将文件直接映射到内存,减少内核空间与用户空间的数据拷贝:
FileChannel channel = new FileInputStream("largefile.dat").getChannel();
MappedByteBuffer mbb = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
四、并行处理与异步IO
- 多线程处理分块文件
将大文件拆分成小块,用线程池并行处理,例如:
ExecutorService executor = Executors.newFixedThreadPool(4);
// 分块逻辑 + 提交任务到线程池
executor.shutdown();
- Java NIO的异步通道(AsynchronousFileChannel)
适用于IO密集型场景,避免线程阻塞:
AsynchronousFileChannel channel = AsynchronousFileChannel.open(Paths.get("file.txt"));
// 异步读取回调处理
五、其他优化技巧
- 压缩大文件传输
使用 GZIPOutputStream/GZIPInputStream 压缩数据,减少IO量。
- 避免字符串拼接导致的频繁GC
处理文本时用 StringBuilder 替代 + 拼接。
- 调整缓冲区大小
根据文件类型和系统内存调整缓冲区(如8KB~64KB),过大可能占用过多内存。
六、性能监控与测试
- 使用 System.nanoTime() 或JMH框架定位瓶颈,对比不同方案的耗时。
- 关注GC日志,避免频繁Full GC影响IO线程响应。