MST

星途 面试题库

面试题:Java中缓冲流提升IO读写效率原理相关 - 性能对比

假设你有一个大文件需要读取,分别使用普通的FileInputStream和BufferedInputStream进行读取操作,从理论和实际代码测试两方面,分析它们在读取性能上的差异,并说明缓冲流提升效率的关键因素有哪些。
12.0万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

理论分析

  1. FileInputStream
    • 每次调用read方法,都会直接从文件系统中读取数据,这涉及到用户态到内核态的切换以及磁盘I/O操作。磁盘I/O相对内存操作来说非常慢,频繁的系统调用会增加额外的开销,导致读取大文件时性能较低。
  2. BufferedInputStream
    • 内部有一个缓冲区(默认大小为8192字节)。首次调用read方法时,它会一次性从文件系统中读取一批数据到缓冲区,后续的read操作优先从缓冲区获取数据。只有当缓冲区数据读完时,才会再次从文件系统读取数据填充缓冲区。这样减少了磁盘I/O操作的次数和用户态到内核态的切换次数,从而提高了读取性能。

实际代码测试

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class FileReadPerformanceTest {
    public static void main(String[] args) {
        String filePath = "largeFile.txt";
        long startTime, endTime;

        // 使用FileInputStream测试
        startTime = System.currentTimeMillis();
        try (FileInputStream fis = new FileInputStream(filePath)) {
            int data;
            while ((data = fis.read()) != -1) {
                // 简单处理,这里可以是实际业务处理
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        endTime = System.currentTimeMillis();
        System.out.println("FileInputStream读取时间: " + (endTime - startTime) + " ms");

        // 使用BufferedInputStream测试
        startTime = System.currentTimeMillis();
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath))) {
            int data;
            while ((data = bis.read()) != -1) {
                // 简单处理,这里可以是实际业务处理
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        endTime = System.currentTimeMillis();
        System.out.println("BufferedInputStream读取时间: " + (endTime - startTime) + " ms");
    }
}

通常情况下,运行上述代码会发现BufferedInputStream的读取时间明显短于FileInputStream

缓冲流提升效率的关键因素

  1. 减少系统调用次数:通过缓冲区,减少了对底层文件系统的直接读取次数,从而减少了用户态到内核态的切换次数,降低了系统开销。
  2. 批量读取数据:一次性从文件系统读取较大的数据块到缓冲区,利用了磁盘I/O的批量传输特性,提高了数据传输效率。
  3. 内存操作优势:从缓冲区读取数据是内存操作,内存访问速度远快于磁盘I/O,在缓冲区数据未读完时,能快速提供数据给应用程序,提升整体性能。