In Java, the BufferedInputStream and BufferedOutputStream classes are used to improve the efficiency of input and output operations by adding a buffer between the program and the input/output source (such as a file or network connection). By buffering the data, fewer I/O operations are performed, which can significantly improve performance, especially for reading and writing large amounts of data.
A buffer is a temporary storage area in memory that holds data before it is processed. Instead of reading or writing data byte-by-byte (which can be slow), a buffer reads or writes data in larger blocks, minimizing the number of interactions with the underlying system (such as a hard drive).
BufferedInputStream is a subclass of FilterInputStream
and adds buffering to an input stream. It wraps around other input streams, such as FileInputStream
, and provides efficient reading of data by reducing the number of I/O operations.
Constructors of BufferedInputStream:
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in, int size) // in: input stream, size: buffer size
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class BufferedInputStreamExample {
public static void main(String[] args) {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("example.txt")){
int data;
while ((data = bis.read()) != -1) {
System.out.print((char) data); // Convert byte to character
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Explanation:
BufferedInputStream
: Wraps the FileInputStream
, adding a buffer for efficient reading.bis.read()
: Reads data from the buffer instead of directly from the file, improving performance.example.txt
character by character.BufferedOutputStream is a subclass of FilterOutputStream
and adds buffering to an output stream. It wraps around other output streams, such as FileOutputStream
, and writes data to the buffer first, then to the destination when the buffer is full or explicitly flushed.
BufferedOutputStream
collects the data in a buffer. When the buffer is full (default size is 8 KB) or explicitly flushed, it writes the entire buffer to the output stream in one operation, reducing the number of writes.Constructors of BufferedOutputStream:
BufferedOutputStream(OutputStream out)
BufferedOutputStream(OutputStream out, int size) // out: output stream, size: buffer size
xxxxxxxxxx
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedOutputStreamExample {
public static void main(String[] args) {
try (BufferedOutputStream bos =
new BufferedOutputStream(new FileOutputStream("output.txt"))) {
String data = "BufferedOutputStream improves writing efficiency!";
bos.write(data.getBytes()); // Convert string to bytes and write to buffer
bos.flush(); // Ensure all buffered data is written to the file
} catch (IOException e) {
e.printStackTrace();
}
}
}
Explanation:
BufferedOutputStream
: Wraps the FileOutputStream
, adding a buffer for efficient writing.bos.write()
: Writes data to the buffer instead of directly to the file.bos.flush()
: Ensures that any remaining data in the buffer is written to the file.output.txt
.Without buffering, every read()
or write()
operation would result in an I/O operation, which is relatively slow. Buffering minimizes these I/O operations by grouping them into larger chunks, thereby improving the program's performance.
read()
: Reads a single byte from the input stream.read(byte[] b, int off, int len)
: Reads bytes into the specified portion of the byte array.available()
: Returns an estimate of the number of bytes that can be read without blocking.mark(int readlimit)
: Marks the current position in the input stream for later resetting.reset()
: Resets the input stream to the previously marked position.close()
: Closes the stream and releases system resources.write(int b)
: Writes a single byte to the output stream.write(byte[] b, int off, int len)
: Writes bytes from the specified byte array to the output stream.flush()
: Forces any buffered output bytes to be written to the underlying output stream.close()
: Closes the stream, flushing any remaining buffered output.Feature | FileInputStream / FileOutputStream | BufferedInputStream / BufferedOutputStream |
---|---|---|
Performance | Slower, as data is read/written byte-by-byte | Faster, as data is read/written in larger chunks (buffered) |
Default Buffer Size | No buffering by default | 8192 bytes (8 KB), can be customized |
Use Case | Suitable for small amounts of data | Suitable for large amounts of data, improves performance |
Typical Operations | Direct access to file or network stream | Buffered access to file or network stream |
Copying a File Using Buffered Streams
This example demonstrates copying a file using BufferedInputStream
and BufferedOutputStream
to improve efficiency.
xxxxxxxxxx
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedCopyFileExample {
public static void main(String[] args) {
try (
BufferedInputStream bis = new BufferedInputStream(new
FileInputStream("sourceFile.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new
FileOutputStream("destinationFile.txt"))){
byte[] buffer = new byte[1024]; // Buffer size is 1024 bytes (1 KB)
int bytesRead;
// Read from the source file into the buffer
while ((bytesRead = bis.read(buffer)) != -1) {
// Write the buffer contents to the destination file
// 0 is the starting index
bos.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Explanation:
BufferedInputStream
: Reads data from sourceFile.txt
in chunks, improving the efficiency of reading.BufferedOutputStream
: Writes data to destinationFile.txt
in chunks, improving the efficiency of writing.