976

How can I check whether a file exists, before opening it for reading in Java (the equivalent of Perl's -e $filename)?

The only similar question on SO deals with writing the file and was thus answered using FileWriter which is obviously not applicable here.

If possible I'd prefer a real API call returning true/false as opposed to some "Call API to open a file and catch when it throws an exception which you check for 'no file' in the text", but I can live with the latter.

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
DVK
  • 126,886
  • 32
  • 213
  • 327
  • 4
    Also want to add that you would want to check for appropriate file permissions: http://docs.oracle.com/javase/6/docs/api/java/io/File.html java.io.File has methods `canRead`, `canWrite`, and `canExecute` to check for that. – Kirkland Mar 26 '15 at 02:03
  • 7
    It should be noted that this is dangerous. The filesystem can change at any time, including right after your "does this file exist" method returns. Since you have to handle that case anyway, such a method is of questionable utility. If you are going to open the file, the correct way to do so is to *open the file* and handle the relevant exception. – Kevin Feb 19 '16 at 05:46
  • 1
    @kevin good point, but it's of unquestionable utility in non-concurrent environment, which happened to be the case I was needing this in ;) – DVK Feb 19 '16 at 05:48
  • @DVK: Are you running on a preemptively multitasked OS? Either that, or it's a [specially designed Java chip](https://xkcd.com/801/). If the former, you are in a concurrent environment. Other processes could change the filesystem out from under you. – Kevin Feb 19 '16 at 05:50
  • 2
    @kevin not that it matters but it's a single threaded app designed for personal use. The chances that it's dedicated file will somehow be created/changed from under it are incredibly low. – DVK Feb 19 '16 at 05:55

19 Answers19

1507

Using java.io.File:

File f = new File(filePathString);
if(f.exists() && !f.isDirectory()) { 
    // do something
}
DVK
  • 126,886
  • 32
  • 213
  • 327
Sean A.O. Harney
  • 23,901
  • 4
  • 30
  • 30
  • 17
    There are some cases where exists() will return an incorrect result. For example, when using an NFS file system there is an issue with stale file handles: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=5003595 It's kind of obscure, but has been the cause of some frustrating bugs in production code before. – CAW Mar 17 '17 at 22:17
  • 61
    Use `if(f.isFile())` instead. – Leon Oct 29 '18 at 01:17
  • 3
    remember to use filePathString.trim() to avoid white spaces – Asim May 01 '19 at 18:46
  • 1
    To clarify @Leon's response, `f.isFile()` returns `false` if `f` is a directory or if it doesn't exist. Thus, it is (mostly) equivalent to `f.exists() && !f.isDirectory()`, though the latter expresses intent more explicitly. – tedtanner Jun 14 '22 at 02:41
484

I would recommend using isFile() instead of exists(). Most of the time you are looking to check if the path points to a file not only that it exists. Remember that exists() will return true if your path points to a directory.

new File("path/to/file.txt").isFile();

new File("C:/").exists() will return true but will not allow you to open and read from it as a file.

DVK
  • 126,886
  • 32
  • 213
  • 327
Chris Dail
  • 25,715
  • 9
  • 65
  • 74
  • 1
    @ylun.ca The example includes subdirectories? If you mean to ask whether, given a current directory of `/path`, `new File("file.txt").exists()` will return `true` if the correct full path is `/path/to/file.txt`, the answer is a big no (unless another file `/path/file.txt` exists). – Matthew Read Jul 10 '15 at 18:16
212

By using nio in Java SE 7,

import java.nio.file.*;

Path path = Paths.get(filePathString);

if (Files.exists(path)) {
  // file exist
}

if (Files.notExists(path)) {
  // file is not exist
}

If both exists and notExists return false, the existence of the file cannot be verified. (maybe no access right to this path)

You can check if path is a directory or regular file.

if (Files.isDirectory(path)) {
  // path is directory
}

if (Files.isRegularFile(path)) {
  // path is regular file
}

Please check this Java SE 7 tutorial.

kc2001
  • 5,008
  • 4
  • 51
  • 92
Wonil
  • 6,364
  • 2
  • 37
  • 55
  • 2
    What is the advatages compared to new File(path).exists() ? For a palin exists check – Raghu K Nair Aug 31 '16 at 18:00
  • 3
    @RaghuKNair `java.nio.file.Files.exists()` is *a lot* faster than `java.io.File.exists()` (from my small benchmark on the only computer I tested: Windows Server 2012 running Java 1.7.0_45 x64). – Matthieu May 16 '17 at 16:53
  • 1
    I just tried it myself and `java.nio.file.Files.exists()` was 5 times **SLOWER** than `java.io.File.exists`. (Win7 Java 1.7.0_79 - x86) – ParkerHalo Oct 12 '17 at 12:33
  • 1
    This also has the disadvantage that Paths.get throws an exception if the string isn't valid – Richard Feb 16 '18 at 17:12
57

Using Java 8:

if(Files.exists(Paths.get(filePathString))) { 
    // do something
}
Wendel
  • 2,809
  • 29
  • 28
  • 2
    `Files.exists()` takes two arguments. Typically, you'll want something like `Files.exists(path, LinkOption.NOFOLLOW_LINKS )`. – Mike C May 25 '17 at 18:28
  • 1
    @MikeC I wonder which method gets called without the second argument. The Docu doesn't even show any information about that. – PowerFlower Jul 28 '17 at 13:54
  • 4
    @PowerFlower: There is only one Files.exists() method. Without passing the second argument, it still calls the same method. The second argument is varargs variable and can pass 0 or more LinkOptions. – TK8 Oct 24 '17 at 20:50
  • Duplicate of an earlier answer. – Lii Jan 24 '22 at 14:16
34
File f = new File(filePathString); 

This will not create a physical file. Will just create an object of the class File. To physically create a file you have to explicitly create it:

f.createNewFile();

So f.exists() can be used to check whether such a file exists or not.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
rizwan
  • 511
  • 5
  • 8
28
f.isFile() && f.canRead()
jhumble
  • 555
  • 4
  • 4
21

There are multiple ways to achieve this.

  1. In case of just for existence. It could be file or a directory.

    new File("/path/to/file").exists();
    
  2. Check for file

    File f = new File("/path/to/file"); 
      if(f.exists() && f.isFile()) {}
    
  3. Check for Directory.

    File f = new File("/path/to/file"); 
      if(f.exists() && f.isDirectory()) {}
    
  4. Java 7 way.

    Path path = Paths.get("/path/to/file");
    Files.exists(path)  // Existence 
    Files.isDirectory(path)  // is Directory
    Files.isRegularFile(path)  // Regular file 
    Files.isSymbolicLink(path)  // Symbolic Link
    
m00am
  • 5,910
  • 11
  • 53
  • 69
Raghu K Nair
  • 3,854
  • 1
  • 28
  • 45
16

Don't. Just catch the FileNotFoundException. The file system has to test whether the file exists anyway. There is no point in doing all that twice, and several reasons not to, such as:

  • double the code
  • the timing window problem whereby the file might exist when you test but not when you open, or vice versa, and
  • the fact that, as the existence of this question shows, you might make the wrong test and get the wrong answer.

Don't try to second-guess the system. It knows. And don't try to predict the future. In general the best way to test whether any resource is available is just to try to use it.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • What if I want to check every hour to see if a file has been deposited on a directly location. I have a webMethods project that has to check to see if a specific file has been uploaded to a specific drive. How would this be done. Let's say that I want to check every hour to see if the file is there. I can use Java to write a class that does this probably with a timer of some sort. – Doug Hauf Jan 23 '14 at 19:21
  • 2
    Catching an exception is way more expensive. In my test, checking new File().exists() was more than 10 times faster than catching FileNotFoundException. So, if you have a scenario where files normally expected to be missing (such as disk cache), exception is wrong. Also, second-guessing the system is cool. – Nick Frolov Jul 05 '14 at 11:43
  • 1
    @Gnawer You haven't addressed any of the issues I raised; the exception is only thrown when the file can't be opened; and operations that occur once an hour don't require micro-optimization. Your final sentence is nonsense. – user207421 Dec 09 '14 at 11:17
  • 2
    @DougHauf in your case there's no issue since you don't attempt to do anything after you check existence. But the OP asked specifically to check before opening. In this case it's better to just try/catch the file open. – Dan Passaro Aug 27 '17 at 13:50
15

You can use the following: File.exists()

blackpanther
  • 10,998
  • 11
  • 48
  • 78
Francis Upton IV
  • 19,322
  • 3
  • 53
  • 57
15

first hit for "java file exists" on google:

import java.io.*;

public class FileTest {
    public static void main(String args[]) {
        File f = new File(args[0]);
        System.out.println(f + (f.exists()? " is found " : " is missing "));
    }
}
blackpanther
  • 10,998
  • 11
  • 48
  • 78
just somebody
  • 18,602
  • 6
  • 51
  • 60
9

For me a combination of the accepted answer by Sean A.O. Harney and the resulting comment by Cort3z seems to be the best solution.

Used the following snippet:

File f = new File(filePathString);
if(f.exists() && f.isFile()) {
    //do something ...
}

Hope this could help someone.

X-Fate
  • 323
  • 4
  • 13
6

I know I'm a bit late in this thread. However, here is my answer, valid since Java 7 and up.

The following snippet

if(Files.isRegularFile(Paths.get(pathToFile))) {
    // do something
}

is perfectly satifactory, because method isRegularFile returns false if file does not exist. Therefore, no need to check if Files.exists(...).

Note that other parameters are options indicating how links should be handled. By default, symbolic links are followed.

From Java Oracle documentation

avi.elkharrat
  • 6,100
  • 6
  • 41
  • 47
  • From sonar docs: _The Files.exists method has noticeably poor performance in JDK 8, and can slow an application significantly when used to check files that don't actually exist._ The same goes for `Files.notExists`, `Files.isDirectory` and `Files.isRegularFile.` The best alternative to this is: `path.toFile().exists()` – Genaut Jan 04 '18 at 09:23
5

It's also well worth getting familiar with Commons FileUtils https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/FileUtils.html This has additional methods for managing files and often better than JDK.

peter.murray.rust
  • 37,407
  • 44
  • 153
  • 217
  • 24
    Way to not answer the question. I agree commons has a lot of useful stuff, but maybe we could take that one step further and provide an answer to the question the OP asked. – demongolem Dec 01 '11 at 16:31
  • 5
    He gave enough of an answer for me. – bulltorious Sep 05 '12 at 19:14
  • It is not uncommon to find Apache Commons Libs are already in use in most projects. I think this answer is very helpful. I can't count the number of times I reinvented the wheel before I finally started using Apache Commons. +1 from me – qualebs Mar 20 '22 at 17:51
1

Don't use File constructor with String.
This may not work!
Instead of this use URI:

File f = new File(new URI("file:///"+filePathString.replace('\\', '/')));
if(f.exists() && !f.isDirectory()) { 
    // to do
}
iviorel
  • 312
  • 3
  • 10
  • May not work why not? And how does using a URI fix that? – user207421 Mar 09 '18 at 15:37
  • We had an issue. f.exists() was true and we even could get the file content. The problem was, the path was wrong but the file name was OK, even this was another file. Changing the constructor call with URI, fixed the problem. – iviorel Mar 12 '18 at 09:23
  • Hard to believe. Using a URI and changing \ to / can't have that effect. You must have fixed something else at the same time. – user207421 Oct 21 '21 at 02:24
1

Simple example with good coding practices and covering all cases :

 private static void fetchIndexSafely(String url) throws FileAlreadyExistsException {
        File f = new File(Constants.RFC_INDEX_LOCAL_NAME);
        if (f.exists()) {
            throw new FileAlreadyExistsException(f.getAbsolutePath());
        } else {
            try {
                URL u = new URL(url);
                FileUtils.copyURLToFile(u, f);
            } catch (MalformedURLException ex) {
                Logger.getLogger(RfcFetcher.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(RfcFetcher.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

Reference and more examples at

https://zgrepcode.com/examples/java/java/nio/file/filealreadyexistsexception-implementations

Amandeep Singh
  • 3,754
  • 8
  • 51
  • 72
  • 1
    The question is about opening it for reading, not writing, and in any case this is certainly not 'good coding practice'. – user207421 Oct 21 '21 at 02:23
0

You can make it this way

import java.nio.file.Paths;

String file = "myfile.sss";
if(Paths.get(file).toFile().isFile()){
    //...do somethinh
}
codeepic
  • 3,723
  • 7
  • 36
  • 57
  • To take into account your answer has the best performance compared with `File.is Exist()` or`Files.isRegularFile()` in JDK 8 – Cristian May 07 '19 at 15:47
0

There is specific purpose to design these methods. We can't say use anyone to check file exist or not.

  1. isFile(): Tests whether the file denoted by this abstract pathname is a normal file.
  2. exists(): Tests whether the file or directory denoted by this abstract pathname exists. docs.oracle.com
Atul Jain
  • 1,035
  • 2
  • 16
  • 24
0

You must use the file class , create a file instance with the path of the file you want to check if existent . After that you must make sure that it is a file and not a directory . Afterwards you can call exist method on that file object referancing your file . Be aware that , file class in java is not representing a file . It actually represents a directory path or a file path , and the abstract path it represents does not have to exist physically on your computer . It is just a representation , that`s why , you can enter a path of a file as an argument while creating file object , and then check if that folder in that path does really exist , with the exists() method .

0

If spring framework is used and the file path starts with classpath:

public static boolean fileExists(String sFileName) {
    if (sFileName.startsWith("classpath:")) {
        String path = sFileName.substring("classpath:".length());
        ClassLoader cl = ClassUtils.getDefaultClassLoader();
        URL url = cl != null ? cl.getResource(path) : ClassLoader.getSystemResource(path);
        return (url != null);
    } else {
        Path path = Paths.get(sFileName);
        return Files.exists(path);
    }
}
Shapur
  • 498
  • 7
  • 17