如何在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个回答

1513

使用java.io.File

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

17
在某些情况下,exists() 方法会返回错误的结果。例如,在使用NFS文件系统时,可能存在陈旧的文件句柄问题:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=5003595这种问题比较难以理解,但在生产代码中曾经导致过一些令人沮丧的错误。 - CAW
62
请使用 if(f.isFile()) - Leon
3
请记得使用 filePathString.trim() 来避免空格。 - Asim
1
为了澄清@Leon的回答,f.isFile()如果f是目录或者不存在则返回false。因此,它(大部分情况下)等效于f.exists() && !f.isDirectory(),尽管后者更明确地表达了意图。 - tedtanner

484

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

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

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


1
@ylun.ca 这个例子包括子目录吗?如果你的意思是问,假设当前目录为/path,当正确的完整路径为/path/to/file.txt时,new File("file.txt").exists()是否会返回true,那么答案是否定的(除非存在另一个文件/path/file.txt)。 - Matthew Read

212

通过在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
}

如果existsnotExists都返回false,则无法验证文件的存在性。(可能没有访问此路径的权限)

您可以检查path是否是目录或普通文件。

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

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

请查看此Java SE 7教程


2
与新File(path).exists()相比,有哪些优势?对于普通的存在检查。 - Raghu K Nair
3
根据我的小型基准测试(在我所测试的唯一计算机上:运行Java 1.7.0_45 x64的Windows Server 2012),java.nio.file.Files.exists()java.io.File.exists() 快得多。 - Matthieu
1
我刚刚亲自尝试了一下,在Win7 Java 1.7.0_79 - x86环境下,java.nio.file.Files.exists()java.io.File.exists慢了5倍。 - ParkerHalo
1
这也有一个缺点,如果字符串无效,Paths.get会抛出异常。 - Richard

57

使用Java 8:

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

2
Files.exists() 接受两个参数。通常,您需要像 Files.exists(path, LinkOption.NOFOLLOW_LINKS ) 这样的东西。 - Mike C
1
@MikeC 我想知道在没有第二个参数的情况下会调用哪种方法。文档甚至没有显示任何相关信息。 - PowerFlower
4
只有一个Files.exists()方法。不传递第二个参数时,它仍然调用相同的方法。第二个参数是可变参数,可以传递0个或多个LinkOptions。 - TK8
之前回答的重复。 - Lii

34
File f = new File(filePathString); 

这不会创建一个实际的文件,只是创建了一个 File 类的对象。要实际创建一个文件,您必须明确地创建它:

f.createNewFile();

因此,f.exists()可以用于检查是否存在这样的文件。


28
f.isFile() && f.canRead()

3
珍珠的 -e 参数是否也可以确保应用程序“能够读取”文件? - lmat - Reinstate Monica

21

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

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

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

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

  • File f = new File("/path/to/file"); 
      if(f.exists() && f.isDirectory()) {}
    
  • 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
    

  • 16

    不需要这样做,只需捕获 FileNotFoundException 异常即可。文件系统必须测试文件是否存在。重复执行这个动作没有意义,而且还有几个原因不要这样做,例如:

    • 代码会增加一倍。
    • 时序窗口问题,即在测试文件存在但打开时不存在或反之的情况。
    • 事实上,就像这个问题的存在一样,您可能会进行错误的测试并得到错误的答案。

    不要试图猜测系统。它知道。也不要试图预测未来。通常测试任何资源是否可用的最佳方法是尝试使用它。


    如果我想每小时检查一次文件是否已经放置在特定位置上,该怎么办?我的webMethods项目必须检查是否已将特定文件上传到特定驱动器。如何操作呢?假设我想每小时检查一次文件是否存在。我可以使用Java编写一个类来完成这个任务,可能需要定时器的帮助。 - Doug Hauf
    2
    捕获异常的代价要高得多。在我的测试中,检查new File().exists()比捕获FileNotFoundException快了10倍以上。因此,如果您有一个通常期望文件丢失的场景(例如磁盘缓存),那么使用异常是错误的。此外,对系统进行第二次猜测是很酷的。 - Nick Frolov
    1
    @Gnawer,你没有解决我提出的任何问题;只有在文件无法打开时才会抛出异常;每小时发生一次的操作不需要微观优化。你最后一句话是无意义的。 - user207421
    2
    @DougHauf 在你的情况下没有问题,因为你在检查存在性后不尝试执行任何操作。但是,OP明确要求在打开文件之前进行检查。在这种情况下,最好只是尝试/捕获文件打开。 - Dan Passaro

    15

    在谷歌上搜索 "java文件是否存在",第一个结果:

    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
    在检查f.exists之前,没有必要先检查f != null是否为真,如果new关键字失败,它会生成一个异常。 - Sean A.O. Harney
    代码相关内容的翻译:没有检查 f != null。f + (...) 使用 java.io.File.toString。 - just somebody
    @just 实际上,它使用 String.valueOf(),可以处理 null 值。 - GreenGiant

    15
    您可以使用以下代码:File.exists()

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