5.1.3 Buffered Streams Explained
Buffered Streams in Java are a type of I/O stream that enhance the performance of input and output operations by reducing the number of direct interactions with the underlying data source. They achieve this by using an internal buffer to temporarily store data, which minimizes the overhead of frequent low-level I/O operations.
Key Concepts
1. Buffering
Buffering is the process of storing data in a temporary memory area (buffer) before it is read or written. This allows the system to handle data in larger chunks, reducing the number of calls to the underlying I/O system, which can be slow and resource-intensive.
Example
import java.io.*; public class BufferedExample { public static void main(String[] args) { try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("input.txt")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) { int data; while ((data = bis.read()) != -1) { bos.write(data); } } catch (IOException e) { e.printStackTrace(); } } }
2. BufferedInputStream
BufferedInputStream
is a subclass of FilterInputStream
that adds buffering to an input stream. It reads data from the underlying input stream in chunks, storing it in an internal buffer. This reduces the number of calls to the underlying input stream, improving performance.
Example
import java.io.*; public class BufferedInputStreamExample { public static void main(String[] args) { try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("input.txt"))) { int data; while ((data = bis.read()) != -1) { System.out.print((char) data); } } catch (IOException e) { e.printStackTrace(); } } }
3. BufferedOutputStream
BufferedOutputStream
is a subclass of FilterOutputStream
that adds buffering to an output stream. It writes data to the underlying output stream in chunks, storing it in an internal buffer. This reduces the number of calls to the underlying output stream, improving performance.
Example
import java.io.*; public class BufferedOutputStreamExample { public static void main(String[] args) { try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) { String data = "Hello, World!"; bos.write(data.getBytes()); } catch (IOException e) { e.printStackTrace(); } } }
4. Buffer Size
The buffer size is the capacity of the internal buffer used by buffered streams. A larger buffer size can improve performance by reducing the number of I/O operations, but it also consumes more memory. The default buffer size is typically 8192 bytes, but it can be specified when creating a buffered stream.
Example
import java.io.*; public class CustomBufferSizeExample { public static void main(String[] args) { try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("input.txt"), 16384); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"), 16384)) { int data; while ((data = bis.read()) != -1) { bos.write(data); } } catch (IOException e) { e.printStackTrace(); } } }
Examples and Analogies
Think of buffered streams as a conveyor belt in a factory. Instead of handling each item (data) individually, the conveyor belt (buffer) collects a batch of items and processes them together. This reduces the number of trips to the processing station (underlying I/O system), making the overall process more efficient.
By using buffered streams, you can significantly improve the performance of your Java applications, especially when dealing with large amounts of data or frequent I/O operations.