如何在Java中检查文件是否存在?

979
在Java中如何检查文件是否存在(相当于Perl的-e $filename)?唯一类似的问题涉及写入文件,因此使用FileWriter进行回答,显然不适用于此处。如果可能,我更喜欢一个真正的API调用返回true/false,而不是一些“调用API打开文件并捕获它抛出的异常,然后检查文本中的'no file'”,但我可以接受后者。

4
还想补充一点,您需要检查适当的文件权限:http://docs.oracle.com/javase/6/docs/api/java/io/File.htmljava.io.File拥有canReadcanWritecanExecute方法来进行检查。 - Kirkland
7
请注意,这样做很危险。文件系统随时可能发生变化,甚至在您的“文件是否存在”方法返回后。既然您必须处理这种情况,这种方法的效用值得怀疑。如果您要打开文件,正确的做法是打开文件并处理相关的异常。 - Kevin
1
@kevin 说得好,但在非并发环境中它的效用是不容置疑的,而这恰好是我需要它的情况 ;) - DVK
@DVK:你是在一个抢占式多任务操作系统上运行吗?要么是这样,要么就是一个专门设计的Java芯片。如果是前者,那么你就处于一个并发环境中。其他进程可能会在你不知情的情况下更改文件系统。 - Kevin
2
@kevin 不是很重要,但这是一个为个人使用设计的单线程应用程序。它的专用文件被创建/更改的可能性非常低。 - DVK
19个回答

9

对我来说,Sean A.O. Harney提供的答案和Cort3z的评论结合起来似乎是最好的解决方案。

使用以下代码片段:

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

希望这能帮助到某些人。

6

我知道我来晚了一些。不过,以下是我的答案,自Java 7以来有效。

以下代码片段:

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

这是完全令人满意的,因为如果文件不存在,则方法isRegularFile返回false。因此,不需要检查Files.exists(...)

请注意,其他参数是指示如何处理链接的选项。默认情况下,符号链接将被跟随。

来自Java Oracle文档


从Sonar文档中: 在JDK 8中,Files.exists方法性能明显较差,并且当用于检查实际不存在的文件时,可能会显著减慢应用程序。对于Files.notExists、Files.isDirectory和Files.isRegularFile也是如此。最好的替代方法是:path.toFile().exists()。 - Genaut

5

24
回避问题的方法。我同意Commons有很多有用的东西,但也许我们可以更进一步,回答提问者所问的问题。 - demongolem
5
他的回答已经足够了。 - bulltorious
在大多数项目中,发现已经在使用Apache Commons Libs并不罕见。我认为这个答案非常有帮助。在我开始使用Apache Commons之前,我无法计算自己重新发明轮子的次数。+1 - qualebs

1

不要使用带有字符串的文件构造函数。
这可能无法正常工作!
改用URI:

File f = new File(new URI("file:///"+filePathString.replace('\\', '/')));
if(f.exists() && !f.isDirectory()) { 
    // to do
}

可能不起作用,为什么呢?使用URI如何解决这个问题? - user207421
我们遇到了一个问题。f.exists() 为真并且我们甚至可以获得文件内容。问题在于路径错误,但文件名正确,即使这是另一个文件。使用 URI 改变构造函数调用,解决了这个问题。 - iviorel
难以置信。使用URI并将\更改为/不可能产生那种效果。您一定同时修复了其他问题。 - user207421

1

一个简单的例子,使用良好的编码实践并覆盖所有情况:

最初的回答:

 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);
            }
        }
    }

参考和更多示例请查看 https://zgrepcode.com/examples/java/java/nio/file/filealreadyexistsexception-implementations。最初的回答。

1
问题是关于打开它以进行读取,而不是写入,在任何情况下,这肯定不是“良好的编码实践”。 - user207421

0

你可以这样做

import java.nio.file.Paths;

String file = "myfile.sss";
if(Paths.get(file).toFile().isFile()){
    //...do somethinh
}

考虑到您的答案在与JDK 8中的File.isExist()Files.isRegularFile()相比具有最佳性能。 - Cristian

0
如果使用Spring框架并且文件路径以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);
    }
}

0

设计这些方法是有特定目的的。我们不能说使用任何一个来检查文件是否存在。

  1. isFile():测试此抽象路径名表示的文件是否为普通文件。
  2. exists():测试此抽象路径名表示的文件或目录是否存在。 docs.oracle.com

0
你必须使用文件类,使用文件路径创建一个文件实例来检查文件是否存在。之后你必须确保它是一个文件而不是一个目录。然后你可以调用exist方法来引用你的文件对象。请注意,Java中的文件类并不代表一个文件,它实际上代表一个目录路径或者文件路径,并且它代表的抽象路径在你的计算机上不必要物理存在。这只是一个表示,因此你可以在创建文件对象时将文件路径作为参数输入,然后检查该路径中的文件夹是否确实存在,使用exists()方法。

1
请提供一些代码。 - Japhei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接