我正在阅读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从缓冲区内存中读取数据?还解释一下。
感谢。
答案 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;
}
}