File Streams in Java

Naveen AnamaneniUpdated · 4 min read
easyJava 25javaiofiles

File streams are the stream classes that connect directly to a file on disk. FileInputStream and FileOutputStream are used to read and write bytes. FileReader and FileWriter are used to read and write characters (text). They are the simplest way to read and write files in java.io, and they are usually wrapped in buffered streams for speed. In this lesson, you will learn their constructors, how to append instead of overwrite, and how to choose a character encoding.

Constructors

ConstructorDescription
new FileInputStream("a.bin")It is used to open a file for reading bytes.
new FileOutputStream("a.bin")It creates or overwrites a file for writing bytes.
new FileOutputStream("a.bin", true)It opens a file for appending bytes.
new FileReader("a.txt", StandardCharsets.UTF_8)It opens a text file for reading with an encoding (Java 11).
new FileWriter("a.txt", StandardCharsets.UTF_8)It creates or overwrites a text file.
new FileWriter("a.txt", StandardCharsets.UTF_8, true)It opens a text file for appending.

If a file to read doesn't exist, the constructor throws FileNotFoundException.

Example: Writing, Appending and Reading Text

Let's see an example that keeps an attendance log.

AttendanceLog.java▶ Try it
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
 
public class AttendanceLog {
    public static void main(String[] args) throws IOException {
        try (FileWriter w = new FileWriter("log.txt", StandardCharsets.UTF_8)) {
            w.write("Navika present\n");
        }
        try (FileWriter w =
                new FileWriter("log.txt", StandardCharsets.UTF_8, true)) {
            w.write("Srihitha present\n");
            w.write("Advitha absent\n");
        }
 
        try (FileReader r = new FileReader("log.txt", StandardCharsets.UTF_8)) {
            char[] buffer = new char[64];
            int n;
            while ((n = r.read(buffer)) != -1) {
                System.out.print(new String(buffer, 0, n));
            }
        }
    }
}
Output
Navika present
Srihitha present
Advitha absent

Explanation: The first FileWriter creates the file. The second opens it with true, so new lines are added at the end instead of replacing the file. Reading uses a char[] buffer: read(buffer) fills the array and returns how many characters it read, which is much faster than reading one character at a time.

Example: A Missing File

Missing.java▶ Try it
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
 
public class Missing {
    public static void main(String[] args) throws IOException {
        try (FileInputStream in = new FileInputStream("marks.dat")) {
            System.out.println(in.read());
        } catch (FileNotFoundException e) {
            System.out.println("Not found: " + e.getMessage());
        }
    }
}
Output
Not found: marks.dat (No such file or directory)

Explanation: Opening a file that doesn't exist throws FileNotFoundException, a subclass of IOException. The message includes the file name and the operating system's reason.

Common Mistakes

Opening a FileWriter without true when you meant to add lines. The old content is erased.

Reading byte by byte from a big file. Use an array buffer or a buffered stream.

Using FileReader for binary files. Use FileInputStream.

Practice

  1. Easy: Append today's date to visits.txt every time the program runs, then print the file.
  2. Harder: Copy a file using FileInputStream and FileOutputStream with an 8 KB byte[] buffer, and print the number of bytes copied.

Quick check: File streams

4 questions
1Which class reads bytes from a file?
2How do you append with FileOutputStream?
3What happens when opening a missing file for reading?
4Why pass StandardCharsets.UTF_8 to FileReader?

Key Takeaways

Was this tutorial helpful?

Lesson 343 of 482