You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中文件写入耗时远超读取的原因探究

Java文件写入与读取性能差异原因分析

我在Java中开展了文件写入与读取的性能测试,测试代码如下:

@Test
public void test_files(){
    File file = new File("a.txt");
    try {
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        byte[] bytes = new byte[1024];

        for (int i = 0; i < 1024; i++) {
            bytes[i] = 1;
        }

        long l = System.currentTimeMillis();

        for (int i = 0; i < 1024*100; i++) {
            fileOutputStream.write(bytes);
            fileOutputStream.flush();
        }
        fileOutputStream.close();
        System.out.println(System.currentTimeMillis()-l);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

@Test
public void test_read_files(){
    File file = new File("a.txt");
    try {
        FileInputStream inputStream = new FileInputStream(file);
        byte[] bytes = new byte[1024];

        long i;
        while ( (i = inputStream.read(bytes)) != -1){
            inputStream.read(bytes);
        }

    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

测试结果:test_files方法(不含字节数组创建环节)耗时约750ms,test_read_files方法耗时约140ms。以下是造成两者性能差异的核心原因:

  • 强制flush是写入性能的最大瓶颈
    写入代码中每次调用write后都执行了fileOutputStream.flush(),这个操作会强制将JVM输出缓冲区、操作系统内核缓冲区中的数据同步到磁盘硬件。磁盘物理写入本身就是慢IO操作,1024*100次的flush相当于触发了十万次磁盘同步写,每一次都要等待磁盘完成寻道、写入、校验的完整流程,这直接拉高了总耗时。而读取操作没有这类强制同步逻辑,完全依托操作系统的缓存优化。

  • 读写的底层硬件与缓存机制天然不对称

    • 磁盘硬件:写操作需要修改磁盘磁道上的数据,涉及寻道、写入、校验等多个物理步骤;而读取操作可以利用磁盘的预读机制,操作系统会提前把相邻的磁盘块加载到内存缓存中,大幅减少磁盘寻道的次数。
    • 操作系统缓存:读取时数据会被缓存到页缓存中,后续读取直接从内存获取;而写入时如果不强制flush,操作系统会攒够一定量的数据再批量写入磁盘,你这里的每次flush直接绕过了这个优化,强制每次写入都落盘。
  • 读取代码的实际IO开销极低
    虽然读取代码存在逻辑问题(while循环中每次调用两次read,会导致部分数据丢失),但操作系统的页缓存会在第一次读取时就把整个文件加载到内存中,后续的读取操作几乎都是从内存缓存中获取,几乎没有真正的磁盘IO开销,所以耗时极低。

内容的提问来源于stack exchange,提问作者yhytsunami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 10:27:26