当前位置: 首页 > 面试题库 >

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

万俟超
2023-03-14
问题内容

我试图使用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;

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

使用BufferedInputStream,该方法将委托给一个重载read()方法,该方法将读取8192一定数量的字节并对其进行缓冲,直到需要它们为止。它仍然仅返回单个字节(但保留其他字节)。这样,BufferedInputStream减少了对操作系统的本地调用以从文件读取。

例如,您的文件为32768字节长。要使用来获取内存中的所有字节FileInputStream,您将需要32768对操作系统进行本地调用。使用BufferedInputStream,您将只需要4,而不管read()您要进行的通话数量(仍然是32768)。

至于如何使其更快,您可能要考虑Java 7的NIO FileChannel类,但是我没有证据支持这一点。

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



 类似资料:
  • 我试图使用FileInputStream将一个文件读入数组,一个~800KB的文件读入内存大约需要3秒钟。然后,我尝试了相同的代码,只是将FileInputStream包装到BufferedInputStream中,耗时约76毫秒。为什么使用BufferedInputStream一个字节一个字节地读取文件要快得多,即使我仍在一个字节一个字节地读取它?下面是代码(其余代码完全无关)。请注意,这是“快

  • bufferedinputstream(BIS)比FileInputStream(FIS)快的原因请参见“为什么使用bufferedinputstream逐字节读取文件比使用FileInputStream快?”?是吗 使用BufferedInputStream,该方法委托给重载read()方法,该方法读取8192个字节,并在FIS读取单个字节时缓冲它们,直到需要它们 据我所知,磁盘是一个“块设备”

  • 问题内容: 我有一个要在Java中读取的2 gb文件(实际上是四个2gb文件)。因此,Java 7中有一个新功能,可以让我一次读取所有字节。 这是一个愚蠢的程序,它将读取文件中预先输入一个字节的文件,然后连续读取该文件,并将读取的内容附加到同一文件中。现在显然,RAM不够大,无法一次读取2gb文件,更不用说其中的四个了,所以我想知道是否有任何快速方法,而无需使用外部库(除非这是唯一方法)来读取四个

  • 关于IO,我有两个问题。 A.在一个教程和一些StackOverflow答案中,他们声称没有被修复。是真的吗? 以下代码使用将数据读入字节数组(1024字节) 从API,有一行: 公共整数读取(字节b[])引发IOException @参数b:将数据读入的缓冲区 B.如果它们都是缓冲的,它们都将数据放入缓冲区,并从缓冲区中获取数据,那么使BufferedInputStream比FileInputS

  • 问题内容: 如何使用fseek逐行读取文件? 代码可能会有所帮助。必须是跨平台和纯PHP。 提前谢谢了 问题答案: 问题是使用fseek进行询问,因此只能假定性能是一个问题,而file()不是解决方案。这是使用fseek的一种简单方法: 我的file.txt 和代码: 输出: 您不必像我一样附加到$ lines数组,如果这是脚本的目的,则可以立即打印输出。如果要限制行数,也很容易引入计数器。

  • 本文向大家介绍Java使用FileInputStream / FileOutputStream读/写文件,包括了Java使用FileInputStream / FileOutputStream读/写文件的使用技巧和注意事项,需要的朋友参考一下 示例 写入文件test.txt: 从文件test.txt中读取: 请注意,自Java 1.7起引入了try-with-resources语句,这使得读/写操