ProgrammingJava Developer

What is an input-output stream (I/O stream) in Java, what are the basics of working with them, and what are the main problems that may arise from incorrect usage of streams?

Pass interviews with Hintsage AI assistant

Answer.

Input-output streams (I/O streams) are one of the fundamental concepts in Java, introduced in the early versions of the language. This concept was initially designed to abstract the processes of reading and writing data: a stream can be linked to a file, a network, or even the console — to the code it all looks the same.

The problem arises when a developer mismanages streams, forgets to close them, or confuses different types of streams (character and byte), often leading to resource leaks, data corruption, or runtime errors.

The solution is a proper understanding and application of the hierarchy of input-output streams (InputStream/OutputStream for bytes, Reader/Writer for characters), as well as the mandatory closure of streams after use, preferably through try-with-resources starting from Java 7.

Example code for reading and writing a file:

try (BufferedReader reader = new BufferedReader(new FileReader("input.txt")); BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) { String line; while ((line = reader.readLine()) != null) { writer.write(line); writer.newLine(); } }

Key features:

  • I/O streams in Java exist in two types: byte (InputStream/OutputStream) and character (Reader/Writer)
  • To enhance efficiency, buffered streams (BufferedReader/BufferedWriter and similar classes) are used
  • Since Java 7, it is recommended to use try-with-resources for automatic closing of streams.

Tricky questions.

What happens if you don't close an I/O stream in Java?

Streams deal with low-level OS resources, and not closing a stream can lead to memory leaks, file locks, application crashes, or even depletion of file descriptors at the OS level.

Can you use the same OutputStream to write to different files?

No, a classic OutputStream is tightly associated with one source/receiver of data. For different files — different OutputStream objects.

What is the difference between PrintWriter and BufferedWriter? When to use which?

PrintWriter specializes in enhancing output with formatted printing methods, like println(), and can work with auto-flushing. BufferedWriter, on the other hand, mainly increases performance through buffering. In most application scenarios, PrintWriter is preferable for text output, but if you only need to quickly write characters or strings without formatting—BufferedWriter is the better choice.

Typical mistakes and anti-patterns

  • Forgetting to close streams after use
  • Using byte streams for text files when character streams are available
  • Writing and reading without buffering, which leads to performance degradation
  • Ignoring/silencing exceptions (like IOException)

Real-life example

Negative case

A developer reads data from a large file using FileInputStream, does not use buffering, and forgets to close the stream.

Pros:

  • The code is short, quickly written

Cons:

  • Reading is slow
  • The file is locked in the file system
  • The application eventually throws exceptions due to resource exhaustion

Positive case

A combination of BufferedReader with try-with-resources is used, reading and processing occur in batches by lines, and the stream automatically closes.

Pros:

  • High performance
  • No resource leaks
  • Easy to maintain and scale

Cons:

  • A bit more code
  • Requires understanding of how Java IO architecture works.