Most of the programs you have written so far store data only temporarily, meaning that information disappears the moment the program finishes running. Real-world applications, however, often need to save data permanently, whether that means storing user records, logging activity, or saving configuration settings that must persist even after the program closes.
Java addresses this need through file handling, a set of classes and methods that allow programs to create, read, write, and manage files stored on a computer's file system. This capability transforms a program from something that only works with temporary, in-memory data into one that can interact with permanent, persistent storage.
In this tutorial, you will learn how to work with the File class, how to write data to files using FileWriter, how to read data from files using FileReader and BufferedReader, and how to handle the exceptions commonly associated with file operations.
File handling refers to the set of operations that allow a Java program to interact with files, including creating new files, writing data into them, reading existing content, and deleting files that are no longer needed. Java provides these capabilities primarily through classes found in the java.io package.
import java.io.File;
public class FileIntroExample {
public static void main(String[] args) {
File channelFile = new File("cs_engineering_gyan.txt");
System.out.println("File name: " + channelFile.getName());
System.out.println("File exists: " + channelFile.exists());
}
}
File name: cs_engineering_gyan.txt File exists: false
In this example, creating a File object does not automatically create the actual file on disk. It simply represents a reference to a file path, which can then be used to check details, create the file, or perform other operations on it.
The File class represents a file or directory path and provides several useful methods for checking properties and performing basic operations, such as creating or deleting a file.
| Method | Description |
|---|---|
| createNewFile() | Creates a new, empty file if it does not already exist. |
| exists() | Checks whether the file already exists at the specified path. |
| delete() | Deletes the file if it exists. |
| getName() | Returns the name of the file. |
| length() | Returns the size of the file in bytes. |
import java.io.File;
import java.io.IOException;
public class FileCreationExample {
public static void main(String[] args) {
try {
File newFile = new File("channel_notes.txt");
if (newFile.createNewFile()) {
System.out.println("CS Engineering Gyan file created: " + newFile.getName());
} else {
System.out.println("File already exists.");
}
} catch (IOException e) {
System.out.println("An error occurred while creating the file.");
}
}
}
CS Engineering Gyan file created: channel_notes.txt
Notice that createNewFile is wrapped inside a try-catch block, since file operations can throw an IOException if something goes wrong, such as insufficient permissions or an invalid file path.
The FileWriter class allows a program to write text data directly into a file. If the specified file does not already exist, FileWriter will create it automatically when data is written.
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterExample {
public static void main(String[] args) {
try {
FileWriter writer = new FileWriter("channel_notes.txt");
writer.write("CS Engineering Gyan - Java Tutorial Series\n");
writer.write("Topic: File Handling in Java\n");
writer.close();
System.out.println("Data written successfully.");
} catch (IOException e) {
System.out.println("An error occurred while writing to the file.");
}
}
}
Data written successfully.
It is important to always call the close() method after writing to a file. This ensures that all data is properly saved and that system resources associated with the file are released correctly.
By default, FileWriter overwrites the existing contents of a file each time it is used. If you want to add new content without erasing what is already there, you can enable append mode by passing an additional parameter.
import java.io.FileWriter;
import java.io.IOException;
public class FileAppendExample {
public static void main(String[] args) {
try {
FileWriter writer = new FileWriter("channel_notes.txt", true);
writer.write("Additional Note: Subscribe to CS Engineering Gyan for more tutorials.\n");
writer.close();
System.out.println("Data appended successfully.");
} catch (IOException e) {
System.out.println("An error occurred while appending to the file.");
}
}
}
Data appended successfully.
Setting the second parameter of the FileWriter constructor to true enables append mode, ensuring new content is added to the end of the file rather than replacing everything that was previously written.
The FileReader class allows a program to read the contents of a text file character by character. While it works well for simple use cases, it is often combined with BufferedReader for more efficient and convenient reading.
import java.io.FileReader;
import java.io.IOException;
public class FileReaderExample {
public static void main(String[] args) {
try {
FileReader reader = new FileReader("channel_notes.txt");
int character;
while ((character = reader.read()) != -1) {
System.out.print((char) character);
}
reader.close();
} catch (IOException e) {
System.out.println("An error occurred while reading the file.");
}
}
}
CS Engineering Gyan - Java Tutorial Series Topic: File Handling in Java Additional Note: Subscribe to CS Engineering Gyan for more tutorials.
The read() method returns one character at a time as an integer value, and returns -1 once the end of the file has been reached, which is used here as the condition to stop the loop.
While FileReader works character by character, BufferedReader allows a program to read an entire line at once, making it a more efficient and convenient choice for reading larger text files.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderFileExample {
public static void main(String[] args) {
try {
BufferedReader reader = new BufferedReader(new FileReader("channel_notes.txt"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (IOException e) {
System.out.println("An error occurred while reading the file.");
}
}
}
CS Engineering Gyan - Java Tutorial Series Topic: File Handling in Java Additional Note: Subscribe to CS Engineering Gyan for more tutorials.
The readLine() method reads one complete line at a time and returns null once there are no more lines left to read, making it easy to process an entire file line by line using a simple loop.
Once a file is no longer needed, Java allows you to delete it directly using the delete() method available through the File class.
import java.io.File;
public class FileDeleteExample {
public static void main(String[] args) {
File file = new File("channel_notes.txt");
if (file.delete()) {
System.out.println("Deleted file: " + file.getName());
} else {
System.out.println("File could not be deleted.");
}
}
}
Deleted file: channel_notes.txt
The delete() method returns a boolean value, allowing your program to confirm whether the deletion was successful or whether an issue prevented the file from being removed.
Java provides a cleaner way to handle files that automatically close resources like readers and writers, even if an exception occurs, without requiring an explicit call to close(). This is known as try-with-resources.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TryWithResourcesExample {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("channel_notes.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("An error occurred while reading the file.");
}
}
}
By declaring the BufferedReader inside the parentheses next to the try keyword, Java automatically closes it once the block finishes executing, even if an exception is thrown, reducing the risk of accidentally leaving files open.
| Class | Purpose |
|---|---|
| FileWriter | Writes character data directly to a file. |
| BufferedWriter | Wraps around a Writer to provide more efficient writing, often used with FileWriter. |
| FileReader | Reads character data directly from a file, one character at a time. |
| BufferedReader | Wraps around a Reader to allow efficient, line-by-line reading. |
| Exception | Common Cause |
|---|---|
| FileNotFoundException | Occurs when attempting to read a file that does not exist at the specified path. |
| IOException | A general exception representing various input or output related errors. |
| SecurityException | Occurs when the program lacks the necessary permissions to access a file. |
| Mistake | Correct Practice |
|---|---|
| Forgetting to close a file after writing to it. | Always call close(), or use try-with-resources to close it automatically. |
| Assuming creating a File object also creates the actual file on disk. | Remember that createNewFile() or a writer must be used to actually create the file. |
| Overwriting a file unintentionally instead of appending to it. | Pass true as the second parameter to FileWriter when append mode is needed. |
| Not handling IOException when performing file operations. | Always wrap file operations inside a try-catch block or declare the exception using throws. |
File handling gives Java programs the ability to interact with permanent storage, allowing data to persist beyond a single execution of the program. By understanding the File class, along with FileWriter, FileReader, and BufferedReader, you gain the tools needed to create, write, read, and delete files confidently.
Using techniques like append mode and try-with-resources further improves how reliably and safely your programs manage files, reducing the risk of data loss or resource leaks. Together with the concepts covered throughout this Java series, from variables and loops to object-oriented programming, exception handling, and collections, file handling completes a strong foundation for building real, practical Java applications.
With this foundation in place, you are well equipped to continue exploring more advanced Java topics, including working with databases, building graphical interfaces, and developing larger, structured software projects.