缓冲流如何在Java内部工作

时间:2015-09-26 17:21:52

标签: java buffer

我正在阅读Buffer Streams。我搜索了一下,找到了许多清楚我的概念的答案,但仍然有更多的问题。

搜索之后,我已经知道,Buffer是临时内存(RAM),它可以帮助程序快速读取数据而不是硬盘。当缓冲区为空时,则为原生input API is called

在阅读之后,我得到了答案from here

  

逐字节地从磁盘读取数据效率非常低。一种方法   加快速度是使用缓冲区:而不是一次读取一个字节,   你一次读取几千个字节,然后将它们放入缓冲区中   记忆。然后你可以逐个查看缓冲区中的字节。

我有两个困惑,

1:如何/谁填充缓冲区中的数据? (原生API如何?)如上所述,谁一次填充千字节?它会消耗相同的时间。假设我有5MB数据,5MB在缓冲区中加载5MB。然后程序在5秒内从缓冲区中使用这些数据。总共10秒。但是如果我跳过缓冲,则程序从1MB / 2sec的硬盘直接获取数据,总数为10Sec。请清除我的这种困惑。

2:第二个这条线是如何工作的

BufferedReader inputStream = new BufferedReader(new FileReader("xanadu.txt"));

因为我在想FileReader将数据写入缓冲区,然后BufferedReader从缓冲区内存中读取数据?还解释一下。

感谢。

2 个答案:

答案 0 :(得分:1)

至于在读/写期间使用缓冲的性能,它可能影响很小,因为操作系统也会缓存,但是缓冲会减少对操作系统的调用次数,这将产生影响。

当您在顶部添加其他操作(例如字符编码/解码或压缩/解压缩)时,影响会更大,因为这些操作在块中完成时效率更高。

你的第二个问题说:

  

因为我在想FileReader将数据写入缓冲区,然后BufferedReader从缓冲区内存中读取数据?还解释一下。

我相信你的想法是对的。是的,从技术上讲,FileReader会将数据写入 a 缓冲区,但缓冲区不是由FileReader定义的,而是由FileReader.read(buffer)方法的调用者定义的。

当某些代码调用BufferedReader.read()(任何重载)时,操作从外部启动。然后BufferedReader将检查它的缓冲区,如果缓冲区中有足够的数据,它将返回数据而不包含涉及FileReader。如果需要更多数据,BufferedReader将调用FileReader.read(buffer)方法来获取下一个数据块。

这是一个拉动操作,而不是推动操作,这意味着调用者将数据从读取器中拉出。

答案 1 :(得分:0)

所有这些东西都是通过一个名为fill()的私有方法完成的,我将其用于教育目的,但是所有java IDE都允许您自己查看源代码:

private void fill() throws IOException {
    int dst;
    if (markedChar <= UNMARKED) {
        /* No mark */
        dst = 0;
    } else {
        /* Marked */
        int delta = nextChar - markedChar;
        if (delta >= readAheadLimit) {
            /* Gone past read-ahead limit: Invalidate mark */
            markedChar = INVALIDATED;
            readAheadLimit = 0;
            dst = 0;
        } else {
            if (readAheadLimit <= cb.length) {
                /* Shuffle in the current buffer */
  // here copy the read chars in a memory buffer named cb
                System.arraycopy(cb, markedChar, cb, 0, delta);
                markedChar = 0;
                dst = delta;
            } else {
                /* Reallocate buffer to accommodate read-ahead limit */
                char ncb[] = new char[readAheadLimit];
                System.arraycopy(cb, markedChar, ncb, 0, delta);
                cb = ncb;
                markedChar = 0;
                dst = delta;
            }
            nextChar = nChars = delta;
        }
    }

    int n;
    do {
        n = in.read(cb, dst, cb.length - dst);
    } while (n == 0);
    if (n > 0) {
        nChars = dst + n;
        nextChar = dst;
    }
}
相关问题