All topics
library
intermediate

Java I/O Streams: Byte vs Character

Distinguish InputStream/OutputStream (bytes) from Reader/Writer (characters) and know when to use each.

Java I/O is divided into two hierarchies: byte streams (InputStream/OutputStream) for raw binary data, and character streams (Reader/Writer) for text with encoding support.

Byte streams = a raw pipe (any liquid flows through). Character streams = a water filter (converts raw water to drinkable, accounting for impurities/encoding).

Key Concepts

1
Byte streams: read/write raw bytes. Use for binary files (images, PDFs, serialized objects), network sockets, and when encoding doesn't matter. Core classes: FileInputStream, FileOutputStream, BufferedInputStream, ByteArrayOutputStream.
2
Character streams: read/write characters with automatic encoding/decoding (UTF-8, etc.). Use for text files, config files, log files. Core classes: FileReader, FileWriter, BufferedReader, PrintWriter. They wrap byte streams with an encoding layer (InputStreamReader, OutputStreamWriter).
3
Buffering: always wrap raw streams in buffered versions. BufferedReader reads large chunks into memory, drastically reducing I/O calls. BufferedInputStream does the same for bytes.
4
Since Java 7, always use try-with-resources to ensure streams are closed. Since NIO.2 (Java 7+), Files.readString(), Files.readAllLines(), and Files.write() handle most simple cases without manually managing streams.