Checking if a file or directory exists is a simple and important operation in many tasks. Before accessing a file, we should check if it exists to avoid a
NullPointerException. The same goes for directories.
While some functions may create a new file/directory if the requested one doesn't exist, this may be the opposite of what we want. If we wish to append more information to an existing file and the method goes through without a warning, since it creates the new file it needs - we may have lost some information without realizing it.
Here, we've got a simple structure:
02/13/2020 11:53 AM <DIR> directory 02/13/2020 11:55 AM <SYMLINKD> directory_link [directory] 02/13/2020 11:53 AM 0 file.txt 02/13/2020 11:55 AM <SYMLINK> symlink.txt [file.txt]
file.txt file and a
symlink.txt file. The
symlink.txt file is a symbolic link to the
Similarly, we've got a
directory and a symbolic link to it -
Check if a File Exists
To work with the
Files class, you need to be acquainted with the
Files only accepts
Path, and not
For the purposes of the tutorial, we'll define a
Path instance for the
file.txt in our directory:
final static String location = "C:\\file.txt"; Path path = Paths.get(location); File file = new File(location);
That being said, the first way we can check if a file exists is through the
// Check if file exists through a Path System.out.println(Files.exists(path)); // Check if a file exists by converting File object to Path System.out.println(Files.exists(file.toPath()));
Running this code will yield us:
You might be wondering why the
notExists() method exists at all:
true, that means that
false. They're logical complements and
A = !B, right?
Well, that's where many get it wrong. If
false, it doesn't have to mean that the file doesn't exist.
It can also mean that the file's existence cannot be verified. In that case, both
Files.notExists() would return
false, as Java cannot determine if the file does or doesn't exist.
This typically happens if you have a file that's locked in a way that Java can't access it. Imagine we had a file that's locked in our directory -
And if we tried verifying its existence with:
We'd be greeted with:
It exists, obviously, but Java doesn't have permission to confirm that on our system - thus giving conflicting results.
Additionally, we can check if the file is a regular file (
false if it's a directory) through the
The output is:
Instead of using the
Files class, we can also perform methods on the file objects themselves:
Similar to the previous option, we can run the
And this also returns:
The difference between these two is that the first one checks if it's a file, and the other one checks if it exists. In different circumstances, they'd return different results.
A fun thing to note is that if you're using a
File to check for existence, Java can determine if the locked file from before exists or not:
Running this piece of code will yield:
With this, it's evident that the locked file can be read by using the
File class instead of the
Files helper class.
Check if a Directory Exists
Directories are essentially files, that can contain other files. This is why checking if a directory is a file will return
true. Though, if you're checking if a directory is a directory (a special type of file), you'll get a more accurate result.
This time around, we're switching our location to:
final static String location = "C:\\directory";
Again, just like in the first example, we can check if it exists via:
The output is:
If we'd like to check if it's specifically a directory, we'd use:
And the output is:
Note: If the directory doesn't exist, the
isDirectory() method will return
false. It's due to the way the method is named. What it does is - it checks if the file exists and if it's a directory, not only the latter. A file can't be a directory if it doesn't exist - hence,
false is returned.
Check if File is Symbolic Link
You might also want to check if a file is just a symbolic link. In that case, you'd use the
Let's switch our location to:
final static String location = "C:\\symlink.txt";
As usual, the
Files class accepts a
Path to the file:
Running this would yield:
File.getCanonicalPath() vs File.getAbsolutePath()
Another way to check for a symbolic link is to compare the results of the file's canonical path and absolute path. If they're different, it's most probably a symbolic link:
Since we're checking for a symbolic link, and we know it is, these should return a different result - a
However, this isn't the case here. This is due to the fact that the symlink was created on Windows with NTFS (New Technology File System). The symlink was created using the
mklink command in the CMD.
Check if Either Exist
From the previous examples, it's evident that the
Files.exists() method will return
true for both existing files and directories. Though, it doesn't work best when it comes to locked files.
On the other hand, the
exists() method from the
File class will also return
true for both files and directories and can read the locked file that the
Files class can't.
Checking for the existence of files and directories is the first line of defense against missing files and directories. Different approaches have different setbacks and you might assume that a method will return an accurate result, but it won't due to how it works in the background.
Being aware of which methods return which results in which circumstances will allow you to avoid nasty exceptions when handling files.
After checking if your file exists or not, you'll likely want to do some Reading and Writing Files in Java.