在Java的BufferedInputStream

时间:2018-04-05 12:35:11

标签: java buffer bufferedinputstream

首先,我理解缓冲作为包装的概念,例如,FileInuptStream作为内容读取的临时容器(让我们从上面读取方案),在这种情况下 - FileInputStream

  1. 说,从流中读取100个字节(文件作为源)。
  2. 如果没有缓冲,代码(read的{​​{1}}方法)必须进行100次读取(一次一个字节)。
  3. 通过缓冲,根据缓冲区大小,代码使< = 100读取。
  4. 假设缓冲区大小为50。
  5. 因此,代码只读取缓冲区(作为源)两次以读取文件的内容。
  6. 现在,由于BufferedInputStream是数据(包含100个字节的文件)的最终来源(尽管由FileInuptStream包裹),因此不必读取100次以读取100字节?但是,代码调用BufferedInputStream的{​​{1}}方法但是,调用会传递给read BufferedInputStream方法,该方法需要进行100次读取调用。这是我无法理解的。
  7. IOW,虽然由read包裹,但基础流(例如FileInuptStream)仍然必须一次读取一个字节。那么,哪些好处(不是只需要两次读缓冲的代码,而是应用程序的性能)的缓冲?

    感谢。

    编辑:

    我将此作为后续跟踪'编辑'而不是评论'因为我觉得它的上下文更适合这里和作为TL;对于@Kayaman和我之间的聊天读者的DR。

    BufferedInputStream的{​​{3}}方法说(摘录):

      

    作为额外的便利,它   尝试通过重复调用来读取尽可能多的字节   读取基础流的方法。此迭代读取继续   直到满足下列条件之一:

    FileInputStream

    我深入研究代码并找到方法调用跟踪,如下所示:

    1. BufferedInputStream - > The specified number of bytes have been read, The read method of the underlying stream returns -1, indicating end-of-file, or The available method of the underlying stream returns zero, indicating that further input requests would block. 我希望看到缓冲行动。
    2. BufferedInputStream - > read(byte b[])
    3. BufferedInputStream - > read(byte b[], int off, int len) - 私人
    4. BufferedInputStream - read(byte b [],int off,int len)
    5. read1(byte[] b, int off, int len) - > FileInputStream - 私人和本地人。源代码中的方法描述 -
    6.   

      将子数组读取为字节序列。

      FileInputStreamreadBytes(byte b[], int off, int len)(上面提到的#4)的呼叫处于无限read1循环中。它返回上面BufferedInputStream方法描述摘录中提到的条件。

      正如我在OP(#6)中提到的,调用似乎确实由与API方法描述和方法调用跟踪匹配的基础流处理。

      问题仍然存在,如果本地API调用 - for read一次读取一个字节并创建要返回的字节数组?

1 个答案:

答案 0 :(得分:1)

  

基础流(例如FileInputStream)仍然必须阅读   一次一个字节

幸运的是,那将是非常低效的。它允许BufferedInputStreamread(byte[8192] buffer)进行FileInputStream次调用,这将调用一大块数据。

如果您想要读取单个字节(或不读取),它将从BufferedInputStream's内部缓冲区有效地返回,而不必转到文件级别。所以BI可以减少我们从文件系统中实际读取的次数,当这些完成后,即使最终用户只想读取几个字节,它们也会以有效的方式完成。

从代码中可以清楚地看出BufferedInputStream.read() 直接委托给UnderlyingStream.read(),因为这会绕过所有缓冲。

public synchronized int read() throws IOException {
    if (pos >= count) {
        fill();
        if (pos >= count)
            return -1;
    }
    return getBufIfOpen()[pos++] & 0xff;
}