Streams in Java provide a flexible and powerful mechanism for handling input and output (I/O) operations, allowing data to be read from and written to various sources and destinations such as files, network connections, and memory buffers.
1. Input and Output Streams
Streams in Java can be broadly classified into two categories:
Input Streams: Used to read data from a source.
Output Streams: Used to write data to a destination.
Byte Streams
Byte streams handle raw binary data and are suitable for all types of I/O, including file, network, and memory operations. The primary classes for byte streams are InputStream and OutputStream.
InputStream: An abstract class representing an input stream of bytes.
OutputStream: An abstract class representing an output stream of bytes.
Character Streams
Character streams handle character data, which makes them suitable for text files. They use Unicode and can handle internationalization. The main classes for character streams are Reader and Writer.
Reader: An abstract class representing a character input stream.
Writer: An abstract class representing a character output stream.
2. Reading and Writing Data
Reading Data
To read data from a source, you use an input stream. Below are examples of reading data using both byte and character streams.
Byte Input Stream Example
import java.io.FileInputStream;
import java.io.IOException;
public class ByteInputStreamExample {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("example.txt")) {
int content;
while ((content = fis.read()) != -1) {
// Convert byte to char and display it
System.out.print((char) content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Character Input Stream Example
import java.io.FileReader;
import java.io.IOException;
public class CharacterInputStreamExample {
public static void main(String[] args) {
try (FileReader fr = new FileReader("example.txt")) {
int content;
while ((content = fr.read()) != -1) {
// Display the character read
System.out.print((char) content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Writing Data
To write data to a destination, you use an output stream. Below are examples of writing data using both byte and character streams.
Byte Output Stream Example
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteOutputStreamExample {
public static void main(String[] args) {
String data = "Hello, World!";
try (FileOutputStream fos = new FileOutputStream("example.txt")) {
// Convert string to bytes and write it to the file
fos.write(data.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Character Output Stream Example
import java.io.FileWriter;
import java.io.IOException;
public class CharacterOutputStreamExample {
public static void main(String[] args) {
String data = "Hello, World!";
try (FileWriter fw = new FileWriter("example.txt")) {
// Write the string to the file
fw.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Conclusion 🎉
Streams in Java are essential for handling I/O operations efficiently. By understanding and using input and output streams, you can read from and write to various sources and destinations, making your Java applications versatile and powerful. The examples provided demonstrate basic usage, but Java streams offer more advanced features such as buffering, filtering, and data serialization, which can be explored further for more complex scenarios.