Java File Class

In the last lesson you learned about Java generics wildcards. Now we move into a brand new area: working with files. Before your program can read or write a file, it needs a way to talk about that file. The File class does exactly that. Letโ€™s learn it.

๐Ÿค” The problem: a program needs to refer to a file

Imagine a program that saves a playerโ€™s high score to scores.txt. Before you write, questions show up:

  • Does scores.txt already exist?
  • Can the program write to that location?
  • Is the folder even there?
  • Skip these checks and the program crashes the first time something is off.

The File class answers these questions. It lives in java.io, so you start with import java.io.File;.

One idea surprises almost everyone:

  • A File object does not hold the contents of a file. It holds a path (the address that points to where a file or folder lives).
  • Think of a house address on paper. The paper is not the house. It just says where the house is.
  • The File object is the paper. The actual file on disk is the house.
  • So creating a File object never touches the disk. It is cheap and always works, even if the file is missing.

๐Ÿ“ Creating a File object

Make a File object that points at a path. You pass the path as a string. Neither line below reads or creates anything on disk.

import java.io.File;
public class Main {
public static void main(String[] args) {
File file = new File("scores.txt"); // โœ… points at a file path
File folder = new File("data"); // โœ… points at a folder path
System.out.println("Created File objects.");
System.out.println("They just hold paths, not contents.");
}
}

Here is what each line does:

  • new File("scores.txt") points at a file named scores.txt in the current working directory.
  • new File("data") points at something named data. Java does not check whether it is a file or a folder.
  • Both lines run instantly. No disk access. The file may or may not exist, and Java does not care yet.

Output

Created File objects.
They just hold paths, not contents.

A path with no folder, like "scores.txt", is looked for in the current working directory (the folder the program runs from). You can also pass a full path like "C:/data/scores.txt" on Windows or "/home/alex/scores.txt" on Linux and Mac.

โ“ Checking what is really there

A File is just a path. So next you want to know what actually exists at that path. Java gives you question-asking methods that each return a boolean. Assume scores.txt is a real file next to the program.

import java.io.File;
public class Main {
public static void main(String[] args) {
File file = new File("scores.txt");
System.out.println("Exists? " + file.exists());
System.out.println("Is a file? " + file.isFile());
System.out.println("Is a folder? " + file.isDirectory());
System.out.println("Can read? " + file.canRead());
System.out.println("Can write? " + file.canWrite());
}
}

Here is what each question does:

  • exists() returns true if a file or folder lives at that path right now.
  • isFile() returns true only for a real, ordinary file.
  • isDirectory() returns true only for a folder.
  • canRead() and canWrite() tell you if the program is allowed to read or write there. Permissions can block you even when the file exists.

Output (assuming scores.txt exists)

Exists? true
Is a file? true
Is a folder? false
Can read? true
Can write? true

The big takeaway: always call exists() before you trust a file. Skip it and you risk reading a file that is not there, or overwriting one you did not mean to.

๐Ÿท๏ธ Reading information about the file

Once a path exists, you often want details about it. How big is it? What is its full address? When was it last changed? This program prints the common ones.

import java.io.File;
import java.util.Date;
public class Main {
public static void main(String[] args) {
File file = new File("scores.txt");
System.out.println("Name: " + file.getName());
System.out.println("Path: " + file.getPath());
System.out.println("Absolute path: " + file.getAbsolutePath());
System.out.println("Size (bytes): " + file.length());
System.out.println("Last modified: " + new Date(file.lastModified()));
}
}

Each method gives you one detail:

  • getName() returns just the name, like scores.txt, no folders in front.
  • getPath() returns the path exactly as you typed it.
  • getAbsolutePath() returns the full path from the root of the disk. Best way to see where Java is really looking.
  • length() returns the size in bytes. For a folder or a missing file, it returns 0.
  • lastModified() returns the last-changed time in milliseconds. Wrap it in new Date(...) for a readable date.

Output (example values)

Name: scores.txt
Path: scores.txt
Absolute path: C:\projects\game\scores.txt
Last modified: Sat Jun 13 10:24:08 IST 2026
Size (bytes): 42

Get a โ€œfile not foundโ€ error but you are sure the file is there? Print getAbsolutePath(). Usually the file is real but sitting in a different folder than the one Java is searching.

๐Ÿ†• Creating files and folders

Now letโ€™s make things. The File class can create an empty file and create folders. These methods do touch the disk, so they can fail and they involve IOException (covered in a moment). The program below creates a file and folders.

import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
File file = new File("notes.txt");
boolean madeFile = file.createNewFile(); // โœ… creates an empty file
System.out.println("Created file? " + madeFile);
File folder = new File("reports");
boolean madeFolder = folder.mkdir(); // โœ… creates one folder
System.out.println("Created folder? " + madeFolder);
File nested = new File("data/2026/june");
boolean madeNested = nested.mkdirs(); // โœ… creates a whole chain
System.out.println("Created nested folders? " + madeNested);
} catch (IOException e) {
System.out.println("Something went wrong: " + e.getMessage());
}
}
}

These creation methods each behave differently:

  • createNewFile() makes a new empty file. Returns true if it made one, false if that name already existed. It never overwrites.
  • mkdir() makes a single folder. Returns false if the parent folder is missing, so it cannot dig deep on its own.
  • mkdirs() makes a folder and every missing parent along the way. Use it for a nested path like data/2026/june in one call.

Output (first run)

Created file? true
Created folder? true
Created nested folders? true

Run the program a second time and the file and folders already exist, so the methods return false. That is normal, not an error.

mkdir vs mkdirs

mkdir() makes only one folder and gives up if a parent is missing. mkdirs() makes the whole chain of folders. When you are not sure the parent folders exist, reach for mkdirs().

๐Ÿ—‘๏ธ Deleting and renaming

The File class can also remove and rename things on disk. Both return a boolean so you can check whether it worked. This program renames a file and deletes another.

import java.io.File;
public class Main {
public static void main(String[] args) {
File oldName = new File("notes.txt");
File newName = new File("notes-2026.txt");
boolean renamed = oldName.renameTo(newName); // โœ… rename or move
System.out.println("Renamed? " + renamed);
File temp = new File("temp.txt");
boolean deleted = temp.delete(); // โœ… remove from disk
System.out.println("Deleted? " + deleted);
}
}

A few things to know:

  • renameTo(newName) changes the name, and it can also move the file if the new path points elsewhere. Returns true on success.
  • delete() removes the file or folder. Returns true if it worked, false if it could not, like when the file is missing or in use.
  • delete() on a folder only works if the folder is empty. Delete what is inside it first.

Output

Renamed? true
Deleted? true

delete() and renameTo() do not throw when they fail. They just return false. So check the return value if you need to be sure.

๐Ÿ“‚ Listing what is inside a folder

A common job is looking inside a folder. The File class gives you two ways:

  • list() returns the names as strings.
  • listFiles() returns full File objects you can ask more questions about.

The program below lists everything inside a folder named reports.

import java.io.File;
public class Main {
public static void main(String[] args) {
File folder = new File("reports");
if (folder.exists() && folder.isDirectory()) { // โœ… check before listing
File[] items = folder.listFiles();
if (items != null) {
for (File item : items) {
String type = item.isDirectory() ? "[folder]" : "[file] ";
System.out.println(type + " " + item.getName());
}
}
} else {
System.out.println("That folder is not available.");
}
}
}

Here are the important parts:

  • folder.listFiles() returns an array of File objects, one per item inside.
  • Each item is itself a File, so you can call isDirectory(), length(), or any method on it.
  • The if (items != null) check matters: listFiles() returns null if the path is not a folder or cannot be read. Looping over null would crash.
  • list() works the same but returns plain String names. Use it when you only need names.

Output (example folder contents)

[file] summary.txt
[file] january.csv
[folder] archive

That null return is a classic trap. listFiles() does not throw when something is wrong. It quietly returns null. Always check before you loop.

โš ๏ธ Files can fail, so handle IOException

Reading a path is safe. Changing the disk is not. A few reasons:

  • The disk could be full.
  • The folder might be read-only.
  • The path might be invalid.

So Java treats createNewFile() as risky and throws a checked exception (an error the compiler forces you to deal with) called IOException. You have two ways to satisfy the compiler:

  • Handle it: wrap the risky call in try and catch.
  • Declare it: add throws IOException so the responsibility passes up to the caller.

Most programs handle it, because you want a friendly message instead of a crash. The example below does that.

import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
File file = new File("output/result.txt");
try {
boolean made = file.createNewFile();
System.out.println("File created? " + made);
} catch (IOException e) {
System.out.println("Could not create the file: " + e.getMessage());
}
}
}

If the folder output is missing, createNewFile() cannot make the file inside it, so it throws an IOException. Because we wrapped the call, the program prints a clear message instead of crashing.

Output (when the output folder is missing)

Could not create the file: The system cannot find the path specified

Remember: exists(), isFile(), length(), and the other question methods do not throw IOException. Only disk-changing methods like createNewFile() force you to handle it.

๐Ÿ”ฎ A note on the modern way

The File class has been in Java since the start, and you will see it everywhere. But it has rough edges:

  • Many methods return false on failure without telling you why. That makes problems hard to track down.
  • So Java 7 added java.nio.file, built around Path (the modern file address) and Files (methods that act on paths).
  • The modern code throws clear exceptions with real messages instead of silently returning false.

Here is the same โ€œcreate a fileโ€ job the modern way, just so you recognize it.

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
Path path = Paths.get("result.txt");
try {
Files.createFile(path); // โœ… modern, throws a clear error on failure
System.out.println("File created.");
} catch (IOException e) {
System.out.println("Could not create the file: " + e.getMessage());
}
}
}

You do not need to master Path and Files today. Just know that File is the classic tool you must understand, and Path/Files is the modern upgrade newer code often prefers.

โš ๏ธ Common Mistakes

A handful of File mistakes catch nearly everyone:

  • Thinking a File holds the fileโ€™s contents. It does not. A File is only a path. To read the contents you need a reader (the next lesson).
// โŒ Wrong idea: a File does not contain the text
File file = new File("scores.txt");
System.out.println(file); // prints the PATH, not the contents
// โœ… A File points at a path; reading comes later with a reader
File scores = new File("scores.txt");
System.out.println("Path points at: " + scores.getAbsolutePath());
  • Not checking exists() first. Trusting that a file is there leads to crashes and wrong results.
// โŒ Assumes the file is there and may behave oddly
File file = new File("scores.txt");
System.out.println(file.length()); // returns 0 if it does not exist, which is misleading
// โœ… Check first, then act
File scores = new File("scores.txt");
if (scores.exists()) {
System.out.println("Size: " + scores.length());
} else {
System.out.println("File is not here yet.");
}
  • Ignoring IOException. createNewFile() is a checked exception, so the compiler will refuse to build until you handle or declare it.
// โŒ Will not compile: IOException is not handled
File file = new File("notes.txt");
file.createNewFile();
// โœ… Wrap it so failures are handled
try {
File notes = new File("notes.txt");
notes.createNewFile();
} catch (IOException e) {
System.out.println("Could not create: " + e.getMessage());
}
  • Looping over listFiles() without a null check. When the path is not a readable folder, listFiles() returns null, and looping over null crashes the program. Always guard it with if (items != null).

โœ… Best Practices

A few habits keep your File code safe and clear.

  • Always check exists() before reading, and check the return value of createNewFile(), delete(), and renameTo() so you know whether the action really happened.
  • Use getAbsolutePath() when debugging a missing file. It shows exactly where Java is looking, which is usually the real problem.
  • Prefer mkdirs() over mkdir() when a folder might have missing parent folders.
  • Guard listFiles() and list() against null before looping over the result.
  • Handle IOException with a clear message for any method that changes the disk, instead of letting the program crash.
  • For new code, look at java.nio.file.Path and Files. They throw clear errors instead of quietly returning false.

๐Ÿงฉ What Youโ€™ve Learned

Nicely done. Letโ€™s recap the File class.

  • โœ… A File object is a path, an address. It does not hold the fileโ€™s contents.
  • โœ… exists(), isFile(), isDirectory(), canRead(), canWrite() answer questions about what is really at a path.
  • โœ… getName(), getPath(), getAbsolutePath(), length(), lastModified() give you details about a file.
  • โœ… createNewFile(), mkdir(), mkdirs(), delete(), renameTo() change the disk, and most return a boolean you should check.
  • โœ… listFiles() and list() show what is inside a folder, and they can return null, so always guard them.
  • โœ… Disk-changing methods like createNewFile() throw the checked IOException, which you must handle or declare. Modern code often uses Path and Files instead.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What does a File object actually hold?

    Why: A File object only stores a path. It does not contain the file's contents.

  2. 2

    Which method makes a folder along with any missing parent folders?

    Why: mkdirs() creates the folder and every missing parent folder in the path. mkdir() only makes a single folder.

  3. 3

    What can listFiles() return when the path is not a readable folder?

    Why: listFiles() returns null in that case, so you must check for null before looping.

  4. 4

    Which method throws a checked IOException that you must handle?

    Why: createNewFile() changes the disk and throws IOException. The question methods like exists() and getName() do not.

๐Ÿš€ Whatโ€™s Next?

Now you can point at files, check them, and create them. The natural next step is to open a file and actually read what is inside it. Next we learn how to read a fileโ€™s contents, both the classic and modern ways.

Java Reading Files

Share & Connect