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

How do I check if a file exists in Java?

提问人:DVK 提问时间:11/30/2009 最后编辑:Arsen KhachaturyanDVK 更新时间:12/11/2022 访问量:1435470

问:

在打开文件进行 Java 读取之前,如何检查文件是否存在(相当于 Perl 的)?-e $filename

SO 上唯一类似的问题涉及编写文件,因此使用该问题回答,这显然不适用于此处。FileWriter

如果可能的话,我更喜欢一个真正的 API 调用返回 true/false,而不是一些“调用 API 打开文件并在它抛出异常时捕获,您检查文本中的”无文件“,但我可以忍受后者。

java 文件- io 文件-存在

评论

4赞 Kirkland 3/26/2015
还想补充一点,您希望检查适当的文件权限:docs.oracle.com/javase/6/docs/api/java/io/File.html java.io.File 有方法 、 ,并检查它。canReadcanWritecanExecute
7赞 Kevin 2/19/2016
应该注意的是,这是危险的。文件系统可以随时更改,包括在“此文件是否存在”方法返回后立即更改。由于无论如何您都必须处理这种情况,因此这种方法的效用值得怀疑。如果要打开文件,正确的方法是打开文件并处理相关异常。
1赞 DVK 2/19/2016
@kevin很好的观点,但它在非并发环境中具有无可置疑的实用性,而这正是我在;)中需要它的情况
0赞 Kevin 2/19/2016
@DVK:您是否在抢占式多任务操作系统上运行?要么是这样,要么是专门设计的 Java 芯片。如果是前者,则您处于并发环境中。其他进程可能会从您下面更改文件系统。
2赞 DVK 2/19/2016
@kevin这并不重要,但它是一个专为个人使用而设计的单线程应用程序。它的专用文件以某种方式从它下面创建/更改的可能性非常低。

答:

1512赞 Sean A.O. Harney 11/30/2009 #1

使用 java.io.File

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

评论

17赞 CAW 3/18/2017
在某些情况下,exists() 将返回不正确的结果。例如,在使用 NFS 文件系统时,陈旧的文件句柄存在问题: bugs.java.com/bugdatabase/view_bug.do?bug_id=5003595 这有点晦涩难懂,但以前一直是生产代码中一些令人沮丧的错误的原因。
62赞 Leon 10/29/2018
请改用。if(f.isFile())
3赞 Asim 5/2/2019
请记住使用 filePathString.trim() 来避免空格
1赞 tedtanner 6/14/2022
为了澄清@Leon的响应,返回 if is a directory or if it isn't exist。因此,它(大部分)等同于 ,尽管后者更明确地表达了意图。f.isFile()falseff.exists() && !f.isDirectory()
15赞 Francis Upton IV 11/30/2009 #2

您可以使用以下命令:File.exists()

15赞 just somebody 11/30/2009 #3

在 Google 上首次点击“Java File Exists”:

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

评论

1赞 Sean A.O. Harney 11/30/2009
在检查 f.exists 之前无需检查 f != null,如果 new 关键字失败,它将生成异常。
0赞 just somebody 11/30/2009
没有检查 f != null。f + (...) 使用 java.io.File.toString
0赞 GreenGiant 1/15/2013
@just实际上,它使用 ,它处理 nullString.valueOf()
5赞 peter.murray.rust 11/30/2009 #4

熟悉 Commons FileUtils 也非常值得 https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/FileUtils.html 这有其他管理文件的方法,而且通常比 JDK 更好。

评论

24赞 demongolem 12/2/2011
不回答问题的方式。我同意 commons 有很多有用的东西,但也许我们可以更进一步,为 OP 提出的问题提供答案。
5赞 bulltorious 9/6/2012
他给了我足够多的答案。
0赞 qualebs 3/21/2022
Apache Commons 库已经在大多数项目中使用,这种情况并不少见。我认为这个答案非常有帮助。在我最终开始使用 Apache Commons 之前,我数不清我重新发明了轮子的次数。+1 从我
484赞 Chris Dail 11/30/2009 #5

我建议使用 代替 .大多数情况下,您希望检查路径是否指向文件,而不仅仅是它存在。请记住,如果您的路径指向目录,则返回 true。isFile()exists()exists()

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

new File("C:/").exists()将返回 true,但不允许你将其作为文件打开和读取。

评论

1赞 Matthew Read 7/11/2015
@ylun.ca 该示例包括子目录?如果你的意思是问,如果正确的完整路径是,给定一个当前目录 ,是否会返回,答案是否定的(除非存在另一个文件)。/pathnew File("file.txt").exists()true/path/to/file.txt/path/file.txt
28赞 jhumble 11/30/2009 #6
f.isFile() && f.canRead()

评论

3赞 lmat - Reinstate Monica 1/5/2013
pearl是否也确保应用程序“可以读取”文件?-e
34赞 rizwan 5/28/2013 #7
File f = new File(filePathString); 

这不会创建物理文件。将只创建类 File 的对象。若要以物理方式创建文件,必须显式创建它:

f.createNewFile();

所以可以用来检查这样的文件是否存在。f.exists()

16赞 user207421 7/18/2013 #8

不要。只需抓住文件系统必须测试文件是否存在。做两次是没有意义的,有几个理由不这样做,例如:FileNotFoundException.

  • 双倍代码
  • 计时窗口问题,即文件可能在测试时存在,但在打开时不存在,反之亦然,以及
  • 事实上,正如这个问题的存在所表明的那样,您可能会进行错误的测试并得到错误的答案。

不要试图对系统进行事后猜测。它知道。不要试图预测未来。一般来说,测试任何资源是否可用的最好方法是尝试使用它。

评论

0赞 Doug Hauf 1/24/2014
如果我想每小时检查一次文件是否已存放在直接位置,该怎么办?我有一个 webMethods 项目,必须检查特定文件是否已上传到特定驱动器。这将如何完成。假设我想每小时检查一次文件是否存在。我可以使用 Java 编写一个类,它可能使用某种计时器来做到这一点。
2赞 Nick Frolov 7/5/2014
捕获异常的成本要高得多。在我的测试中,检查 new File().exists() 比捕获 FileNotFoundException 快 10 倍以上。因此,如果您遇到通常预期丢失的文件(例如磁盘缓存)的情况,则异常是错误的。此外,对系统进行二次猜测很酷。
1赞 user207421 12/9/2014
@Gnawer 你还没有解决我提出的任何问题;仅当文件无法打开时才会引发异常;每小时发生一次的操作不需要微优化。你的最后一句话是胡说八道。
2赞 Dan Passaro 8/27/2017
@DougHauf,就您而言,没有问题,因为您在检查存在后不会尝试做任何事情。但OP特别要求在打开前进行检查。在这种情况下,最好只是尝试/捕获打开的文件。
212赞 Wonil 8/22/2013 #9

通过在 Java SE 7 中使用 nio,

import java.nio.file.*;

Path path = Paths.get(filePathString);

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

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

如果两者都返回 false,则无法验证文件是否存在。(也许没有访问此路径的权限)existsnotExists

您可以检查是目录文件还是常规文件。path

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

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

请查看此 Java SE 7 教程

评论

2赞 Raghu K Nair 9/1/2016
与新的 File(path).exists() 相比,有什么优势?对于 palin 存在检查
3赞 Matthieu 5/17/2017
@RaghuKNair比(从我测试的唯一一台计算机上的小型基准测试:运行 Java 1.7.0_45 x64 的 Windows Server 2012)快得多java.nio.file.Files.exists()java.io.File.exists()
1赞 ParkerHalo 10/12/2017
我只是自己尝试了一下,比 .(Win7 Java 1.7.0_79 - x86)java.nio.file.Files.exists()java.io.File.exists
1赞 Richard 2/17/2018
这也有一个缺点,即如果字符串无效,Paths.get 会引发异常
9赞 X-Fate 1/21/2015 #10

对我来说,Sean A.O. Harney 接受的答案和 Cort3z 由此产生的评论的结合似乎是最好的解决方案。

使用了以下代码片段:

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

希望这可以帮助某人。

57赞 Wendel 6/1/2016 #11

使用 Java 8:

if(Files.exists(Paths.get(filePathString))) { 
    // do something
}

评论

2赞 Mike C 5/26/2017
Files.exists()需要两个参数。通常,您需要类似 .Files.exists(path, LinkOption.NOFOLLOW_LINKS )
1赞 PowerFlower 7/28/2017
@MikeC我想知道在没有第二个参数的情况下调用哪个方法。Docu 甚至没有显示任何有关此的信息。
4赞 TK8 10/25/2017
@PowerFlower:只有一个 Files.exists() 方法。在不传递第二个参数的情况下,它仍调用相同的方法。第二个参数是 varargs 变量,可以传递 0 个或多个 LinkOptions。
0赞 Lii 1/24/2022
与先前的答案重复。
21赞 Raghu K Nair 9/1/2016 #12

有多种方法可以实现这一点。

  1. 如果只是为了存在。它可以是文件或目录。

    new File("/path/to/file").exists();
    
  2. 检查文件

    File f = new File("/path/to/file"); 
      if(f.exists() && f.isFile()) {}
    
  3. 检查目录。

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

    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
    
1赞 iviorel 12/1/2016 #13

不要将 File 构造函数与 String 一起使用。
这可能行不通!
而不是这样,请使用 URI:

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

评论

0赞 user207421 3/9/2018
可能行不通,为什么不行?使用 URI 如何解决这个问题?
0赞 iviorel 3/12/2018
我们遇到了一个问题。f.exists() 为 true,我们甚至可以获取文件内容。问题是,路径错误,但文件名没问题,即使这是另一个文件。使用 URI 更改构造函数调用,解决了该问题。
0赞 user207421 10/21/2021
难以置信。使用 URI 并将 \ 更改为 / 不会产生这种效果。您必须同时修复了其他内容。
6赞 avi.elkharrat 9/19/2017 #14

我知道我在这个线程中有点晚了。但是,这是我的答案,自 Java 7 及更高版本以来有效。

以下代码片段

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

是完全满意的,因为如果文件不存在,方法会返回。因此,无需检查 .isRegularFilefalseFiles.exists(...)

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

来自 Java Oracle 文档

评论

0赞 Genaut 1/4/2018
来自声纳文档:Files.exists 方法在 JDK 8 中的性能明显较差,并且在用于检查实际上不存在的文件时会显着降低应用程序的速度。这同样适用于 ,最好的替代方案是:Files.notExistsFiles.isDirectoryFiles.isRegularFile.path.toFile().exists()
0赞 Rodrigo Pavan 10/17/2018 #15

你可以这样做

import java.nio.file.Paths;

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

评论

0赞 Cristian 5/7/2019
要考虑到您的答案与 JDK 8 相比或在 JDK 8 中具有最佳性能File.is Exist()Files.isRegularFile()
1赞 Amandeep Singh 3/4/2019 #16

具有良好编码实践并涵盖所有情况的简单示例:

 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 10/21/2021
问题在于打开它进行阅读,而不是写作,无论如何,这肯定不是“好的编码实践”。
0赞 Atul Jain 5/3/2019 #17

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

  1. isFile():测试这个抽象路径名所表示的文件是否是普通文件。
  2. exists():测试由此抽象路径名表示的文件或目录是否存在。docs.oracle.com
0赞 user10525734 7/9/2022 #18

您必须使用 file 类 ,创建一个文件实例,其中包含要检查的文件路径是否存在。之后,您必须确保它是一个文件而不是 目录 .之后,您可以在引用文件的文件对象上调用 exist 方法。请注意,java中的文件类并不代表文件。它实际上代表一个目录路径或一个文件路径,它所代表的抽象路径不必物理存在于你的计算机上。它只是一个表示,这就是为什么,你可以在创建文件对象时输入一个文件的路径作为参数,然后用exists()方法检查该路径中的那个文件夹是否真的存在。

评论

1赞 Japhei 7/10/2022
请提供一些代码。
0赞 Shapur 12/11/2022 #19

如果使用 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);
    }
}