java - 为什么使用 BufferedInputStream 逐字节读取文件比使用 FileInputStream 快?

标签 java file-io inputstream fileinputstream

我试图使用 FileInputStream 将一个文件读入一个数组,一个约 800KB 的文件需要大约 3 秒才能读入内存。然后我尝试了相同的代码,除了将 FileInputStream 包装到 BufferedInputStream 中,它花费了大约 76 毫秒。为什么使用 BufferedInputStream 逐字节读取文件的速度要快得多,即使我仍在逐字节读取它?这是代码(其余代码完全不相关)。请注意,这是“快速”代码。如果你想要“慢”代码,你可以删除 BufferedInputStream:

InputStream is = null;

    try {
        is = new BufferedInputStream(new FileInputStream(file));

        int[] fileArr = new int[(int) file.length()];

        for (int i = 0, temp = 0; (temp = is.read()) != -1; i++) {
            fileArr[i] = temp;
        }

BufferedInputStream 快 30 倍以上。远不止于此。那么,这是为什么呢,是否有可能让这段代码更高效(不使用任何外部库)?

最佳答案

FileInputStream 中,方法read() 读取单个字节。来自源代码:

/**
 * Reads a byte of data from this input stream. This method blocks
 * if no input is yet available.
 *
 * @return     the next byte of data, or <code>-1</code> if the end of the
 *             file is reached.
 * @exception  IOException  if an I/O error occurs.
 */
public native int read() throws IOException;

这是对使用磁盘读取单个字节的操作系统的 native 调用。这是一项繁重的操作。

使用 BufferedInputStream,该方法委托(delegate)给重载的 read() 方法,该方法读取 8192 数量的字节并缓冲它们,直到它们需要。它仍然只返回单个字节(但保留其他字节)。这样,BufferedInputStream 对操作系统的 native 调用减少以从文件中读取。

例如,您的文件是 32768 字节长。要使用 FileInputStream 获取内存中的所有字节,您需要对操作系统进行 32768 native 调用。使用 BufferedInputStream,您将只需要 4,无论您将执行多少次 read() 调用(仍然是 32768)。

至于如何让它更快,你可能想考虑 Java 7 的 NIO FileChannel 类,但我没有证据支持这一点。


注意:如果您直接使用 FileInputStreamread(byte[], int, int) 方法,则使用 byte[>8192] 你不需要 BufferedInputStream 包装它。

关于java - 为什么使用 BufferedInputStream 逐字节读取文件比使用 FileInputStream 快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18600331/

相关文章:

java - 在 Java 程序之间共享 I/O

Java - 从 S3 对象逐行读取 (JSON) 数据

java - 在 Java 中关闭输入流

java - 为什么我的垂直乘积求和程序出现 "index out of bounds"异常?

java - 使用 ActiveMQ 5,是否可以在内存和网络连接中配置代理?

java - 使用 bcrypt 进行 Spring 身份验证

java - 如何使我的布局在不同的屏幕尺寸上缩放?

java - 文件 I/O 错误

java - 使用 datainput/-outputstream 通过 java 套接字发送 jpg-图像时出现问题

file-io - 英特尔 Fortran 形式的标准等效项 = 'binary'