我知道BufferedWriter
或BufferedReader
无法直接与文件通信。它需要包装另一个Writer
对象来执行此操作。像,
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("abc.txt"));
我们只是使用FileWriter
包裹BufferedWriter
对象,以获得IO性能优势。
但我也可以这样做,
BufferedWriter bufferedWriter = new BufferedWriter(new BufferedWriter(new FileWriter("abc.txt")));
这里使用BufferedWriter包装FileWrite对象,而BufferedWriter又使用另一个BufferedWriter包装。或者更邪恶的想法就是将它进一步链接起来。
双BufferedWriter有什么真正的优势吗?或者进一步链接它?这同样适用于BufferedReader。
答案 0 :(得分:3)
没有任何好处,没有。
首先,您必须了解缓冲的用途。当您写入磁盘时,硬盘驱动器需要将磁盘头物理移动到正确的位置,然后等待磁盘旋转以使其位于正确的位置,然后然后开始写入字节作为磁盘旋转在头下。相对而言,前两个步骤比其余操作慢得多。这意味着有很多固定的开销:写入1000个字节比写入1个字节1000次要快得多。
因此,缓冲只是让应用程序写入字节的一种方式,这种方式对应用程序的逻辑很容易 - 一次一个字节,三个字节,1000个字节,等等 - 同时仍然获得磁盘性能。对缓冲区的大多数写操作实际上不会导致任何字节转到底层输出流;只有当你达到一定的限度(比如说,每1000个字节)时,才会同时写下所有内容。
这与输入相同。
所以,链接这些将无济于事。对于链,假设它们具有相同的缓冲区大小,您将写入“外部”缓冲区,并且根本不会写入“内部”缓冲区...然后当它达到其限制时,它将刷新所有那些字节到内部缓冲区。该内部缓冲区立即达到其缓冲区限制(因为它们是相同的限制)并将这些字节直接刷新到输出。你没有任何好处,但你必须在内存中复制字节一段额外的时间(到字节缓冲区)。
答案 1 :(得分:0)
“缓冲”这里主要反映了接口(API)的语义。注意到这一点,通过链接BufferedReader
组成IO管道是可能的。一般来说,考虑到链末端单个字节的消耗可能涉及头部的多次读取,理论上和每个API可能只是基于头部读取数据的计算 。
对于块设备缓冲的一般情况(例如,从具有块大小的数据传输的IO设备读取,例如FS或网络端点),链接缓冲区(有效队列)肯定会增加内存消耗,立即增加处理延迟(由于缓冲区大小增加,总计)。它通常会显着提高吞吐量(对延迟产生负面影响)。