为什么使用BufferedInputStream比使用FileInputStream更快地读取文件? [英] Why is using BufferedInputStream to read a file byte by byte faster than using FileInputStream?

查看:1082
本文介绍了为什么使用BufferedInputStream比使用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()]; (int i = 0,temp = 0;(temp = is.read())!= -1; i ++){
fileArr [i] = temp;


}

BufferedInputStream速度超过30倍。远不止这些。那么,为什么会这样,而且是否有可能使这个代码更有效率(不使用任何外部库)呢? 解决方案

FileInputStream ,方法 read()读取一个字节。从源代码:

  / ** 
*从这个输入流中读取一个字节的数据。如果没有输入可用,这个方法阻止
*。
*
* @返回数据的下一个字节,或者< code> -1< / code>如果到达
*文件的末尾。
* @exception IOException如果发生I / O错误。
* /
public native int read()throws IOException;

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

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



例如,是 32768 字节长。要使用 FileInputStream 获取内存中的所有字节,您将需要 32768 本地调用操作系统。使用 BufferedInputStream ,无论 read()的数量如何,只需要 4 调用你会做(仍然 32768 )。



至于怎么做更快一些,你可能想要考虑Java 7的NIO FileChannel 类,但是我没有证据支持这个。


I was trying to read a file into an array by using FileInputStream, and an ~800KB file took about 3 seconds to read into memory. I then tried the same code except with the FileInputStream wrapped into a BufferedInputStream and it took about 76 milliseconds. Why is reading a file byte by byte done so much faster with a BufferedInputStream even though I'm still reading it byte by byte? Here's the code (the rest of the code is entirely irrelevant). Note that this is the "fast" code. You can just remove the BufferedInputStream if you want the "slow" code:

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 is over 30 times faster. Far more than that. So, why is this, and is it possible to make this code more efficient (without using any external libraries)?

解决方案

In FileInputStream, the method read() reads a single byte. From the source code:

/**
 * 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;

This is a native call to the OS which uses the disk to read the single byte. This is a heavy operation.

With a BufferedInputStream, the method delegates to an overloaded read() method that reads 8192 amount of bytes and buffers them until they are needed. It still returns only the single byte (but keeps the others in reserve). This way the BufferedInputStream makes less native calls to the OS to read from the file.

For example, your file is 32768 bytes long. To get all the bytes in memory with a FileInputStream, you will require 32768 native calls to the OS. With a BufferedInputStream, you will only require 4, regardless of the number of read() calls you will do (still 32768).

As to how to make it faster, you might want to consider Java 7's NIO FileChannel class, but I have no evidence to support this.

这篇关于为什么使用BufferedInputStream比使用FileInputStream更快地读取文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆