A Comprehensive Guide to Reading and Writing Files in Java

Atanda Oluchi Aminat
Towards Dev
Published in
5 min readMay 6, 2024

--

In the world of programming, handling file operations is a crucial skill. Java Programming language provides powerful tools and libraries to efficiently read from and write to files. So, whether you are working with text files, binary files, or even CSVs, Java’s File I/O capabilities are robust and flexible. In this article, we’ll explore the various ways to perform file operations in Java.

1. Reading from Text Files:

Reading from a text file in Java is straightforward. Here’s a basic example of how to do that with comments to explain each line of code:

/* 
***

import the necessary classes from the java.io package for reading files.
BufferedReader is used for efficient reading of characters and
FileReader is used to read the contents of a file

***
*/
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderExample { //Defining class FileReaderExample
public static void main(String[] args) {
//main method (the entry point of the Java program)

/*
declare a String variable to store the path of the text file
you want to read. You should replace "path/to/your/file.txt" with the
actual path to your file.
*/
String filePath = "path/to/your/file.txt";

/*
Begin a try catch block. Initialize the `BufferedReader` with a new
instance of `FileReader` that takes `filePath` as an argument.
This ensures that the file is opened for reading.

The `BufferedReader` allows us to read the text from the input stream
efficiently by buffering the characters.

The try catch statement ensures that the `BufferedReader` is closed
automatically after the try block finishes, whether an exception occurs or not.
This is important for resource management and avoids memory leaks.

*/
try (BufferedReader br =
new BufferedReader(new FileReader(filePath))) {
//Declare a `String` variable to store each line read from the file.
String line;
/*
There should be a while loop that reads each line from the file until
readLine() returns `null`, indicating the end of the file.
That means the loop continues as long as `readLine()` does not return `null`.

br.readline reads a line of text. Each time it's called,
it advances to the next line in the file. We would assign each line of text
read to the string created earlier (in our case here, the string is line)
*/
while ((line = br.readLine()) != null) {

/*
Inside the loop, each line read from the file is printed to the console
using `System.out.println()`. This will display the contents of the file
line by line.
*/
System.out.println(line);
}
// End of the while loop.
} catch (IOException e) {
/*
If an `IOException` occurs during the reading process, the program will
catch the exception here.

*/

/*
This line prints an error message to the standard error
stream (`System.err`) along with the specific error message
provided by the `IOException` (`e.getMessage()`).
*/
System.err.println("Error reading file: " + e.getMessage());
}
}
}

2. Writing to Text Files:

Writing to a text file involves similar steps:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterExample {
public static void main(String[] args) {
String filePath = "path/to/your/output.txt";
try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath))) {
bw.write("Hello, world!\n");
bw.write("This is a line written to the file.");
} catch (IOException e) {
System.err.println("Error writing to file: " + e.getMessage());
}
}
}

Code Explanation:

import java.io.BufferedWriter; and import java.io.FileWriter;:

These lines import the necessary classes from the java.io package for writing files. BufferedWriter is used for efficient writing of characters, and FileWriter is used to write characters to a file.

public class FileWriterExample {:

This line defines a class named FileWriterExample.

public static void main(String[] args) {:

This is the main method, the entry point of the Java program.

String filePath = "path/to/your/output.txt";:

This line declares a String variable named filePath and assigns it the path to the text file you want to write to. You should replace "path/to/your/output.txt" with the actual path to your file.

try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath))) {:

This is the beginning of a try-with-resources block. The BufferedWriter is initialized with a new instance of FileWriter that takes filePath as an argument. This ensures that the file is opened for writing.

The BufferedWriter allows us to write text to the output stream efficiently by buffering the characters.

The try-with-resources statement ensures that the BufferedWriter is closed automatically after the try block finishes, whether an exception occurs or not. This is important for resource management and avoids memory leaks.

bw.write("Hello, world!\n"); and bw.write("This is a line written to the file.");:

These lines write text to the file using the write() method of the BufferedWriter. Each write() call adds text to the file. This \n is used to insert a newline character.

} catch (IOException e) {:

If an IOException occurs during the writing process, the program will catch the exception here.

System.err.println("Error writing to file: " + e.getMessage());:

This line prints an error message to the standard error stream (System.err) along with the specific error message provided by the IOException (e.getMessage()).

}:

End of the try-catch block.

3. Reading and Writing Binary Files:

For binary files, you would use streams like FileInputStream and FileOutputStream:

import java.io.*;
public class BinaryFileExample {
public static void main(String[] args) {
String inputFilePath = "path/to/binary/input.dat";
String outputFilePath = "path/to/binary/output.dat";
try (FileInputStream fis = new FileInputStream(inputFilePath);
FileOutputStream fos = new FileOutputStream(outputFilePath)) {
int byteRead;
while ((byteRead = fis.read()) != -1) {
fos.write(byteRead);
}
} catch (IOException e) {
System.err.println("Error handling binary file: " + e.getMessage());
}
}
}

4. Using Java NIO for Advanced File Operations:

Java NIO (New I/O) provides a more efficient and flexible way to perform file operations. Here’s a quick example:

import java.nio.file.*;
import java.io.IOException;
import java.util.List;
public class NIOFileExample {
public static void main(String[] args) {
Path filePath = Paths.get("path/to/your/file.txt");
try {
List<String> lines = Files.readAllLines(filePath);
for (String line : lines) {
System.out.println(line);
}
// Writing to a file using NIO
List<String> dataToWrite = List.of("Line 1", "Line 2", "Line 3");
Files.write(filePath, dataToWrite, StandardOpenOption.CREATE);
} catch (IOException e) {
System.err.println("Error reading/writing file: " + e.getMessage());
}
}
}

5. Handling Exceptions:

When working with file I/O, always handle exceptions properly to ensure your program doesn’t crash unexpectedly. Use try and catch for automatic resource management and clean-up.

Conclusion:

In this guide, we’ve covered the basics of reading and writing files in Java. Whether it’s simple text files, binary files, or more advanced file operations using Java NIO, you now have the knowledge to handle file I/O effectively in your Java programs. Remember to handle exceptions, close resources properly, and explore Java’s vast libraries for more advanced file operations.

File handling is a fundamental aspect of programming, and mastering it will empower you to work with various types of data and external resources in your Java applications.

--

--