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


841

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

关于SO的唯一类似问题是写文件,因此得到了回答FileWriter,显然在这里不适用。

如果可能的话,我宁愿使用真正的API调用返回true / false,而不是使用“调用API来打开文件并在引发异常时捕获并在文本中检查'无文件'的情况下捕获”,但是我可以接受后者。


3
也想补充一点,你会要检查相应的文件权限: docs.oracle.com/javase/6/docs/api/java/io/File.html 的java.io.File有方法canReadcanWrite以及canExecute以检查。
柯克兰

6
应当指出,这很危险。文件系统可以随时更改,包括在您的“此文件存在”方法返回后立即更改。由于无论如何都必须处理这种情况,因此这种方法的实用性值得怀疑。如果要打开文件,正确的方法是打开文件并处理相关异常。
凯文

1
@kevin好点,但是在非并行环境中它无疑是有用的,这恰好是我在其中需要的情况;)
DVK 2016年

@DVK:您是否在抢先式多任务操作系统上运行?要么,要么是专门设计的Java芯片。如果是前者,则您处于并发环境中。其他进程可能会将文件系统从您身下移开。
凯文

2
@kevin并不重要,但这是一个为个人使用而设计的单线程应用程序。从其下方创建/更改它的专用文件的机会非常低。
DVK

Answers:


1341

使用java.io.File

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

15
在某些情况下,exist()将返回错误的结果。例如,当使用NFS文件系统时,过时的文件句柄会出现问题:bugs.java.com/bugdatabase/view_bug.do?bug_id=5003595 有点晦涩难懂,但却是导致生产代码中一些令人沮丧的错误的原因之前。
COW

22
使用if(f.isFile())代替。
莱昂,

1
记得使用filePathString.trim()来避免空格
Asim

426

我建议使用isFile()代替exists()。大多数时候,您都希望检查路径是否不仅指向文件而且还指向文件。请记住,exists()如果您的路径指向目录,它将返回true。

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

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


1
@ ylun.ca该示例包括子目录吗?如果你的意思是问是否给出的当前目录/pathnew File("file.txt").exists()将返回true如果正确的完整路径是/path/to/file.txt,答案是一大禁忌(除非另一个文件/path/file.txt存在)。
马修(Matthew)

149

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

2
@RaghuKNair java.nio.file.Files.exists()很多快于java.io.File.exists()(从我的唯一的计算机上的小基准我测试:在Windows Server 2012上运行Java 1.7.0_45 64位)。
Matthieu

1
我自己尝试过,速度java.nio.file.Files.exists() 5倍。(Win7 Java 1.7.0_79-x86)java.io.File.exists
ParkerHalo

这也有一个缺点,即如果字符串无效,Paths.get会引发异常
理查德(Richard)

46

使用Java 8:

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

2
Files.exists()有两个参数。通常,您会需要Files.exists(path, LinkOption.NOFOLLOW_LINKS )
Mike C

1
@MikeC我想知道在没有第二个参数的情况下调用哪个方法。Docu甚至没有显示任何有关此的信息。
PowerFlower

1
@PowerFlower:只有一个Files.exists()方法。在不传递第二个参数的情况下,它仍然调用相同的方法。第二个参数是varargs变量,可以传递0个或多个LinkOptions。
TK8

27
File f = new File(filePathString); 

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

f.createNewFile();

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



16

有多种方法可以实现此目的。

  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
    


14

在Google上首次匹配“ 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 AO Harney

没有检查f!= null。F +(...)使用java.io.File.toString
只是有人

@just实际上,它使用String.valueOf()处理空值的
GreenGiant

12

别。只需捕获FileNotFoundException.文件系统就必须测试文件是否仍然存在。重复两次都是没有意义的,有几个原因不这样做,例如:

  • 将代码加倍
  • 计时窗口问题,因此当您测试该文件可能存在,但不是当你打开,或者反之亦然,
  • 正如该问题的存在所表明的那样,您可能会进行错误的测试并获得错误的答案。

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


如果我想每小时检查一次文件是否已经存放在直接位置上,该怎么办?我有一个webMethods项目,必须检查以查看是否已将特定文件上载到特定驱动器。怎么做。假设我想每小时检查一次文件是否存在。我可以使用Java编写一个可能使用某种计时器执行此操作的类。
Doug Hauf 2014年

2
捕获异常的代价更高。在我的测试中,检查新File()。exists()的速度比捕获FileNotFoundException的速度快10倍以上。因此,如果您遇到通常期望丢失文件(例如磁盘缓存)的情况,则错误是错误的。另外,第二种猜测是很酷的。
尼克·弗罗洛夫

1
@Gnawer您尚未解决我提出的任何问题;仅在无法打开文件时抛出异常;每小时执行一次的操作不需要进行微优化。你的最后一句废话。
user207421 2014年

1
在您的情况下,@ DougHauf没有问题,因为您在检查存在之后不尝试执行任何操作。但是OP专门要求在打开之前进行检查。在这种情况下,最好只是尝试/捕获打开的文件。
丹·帕萨罗

8

对我而言,Sean AO Harney接受的答案与Cort3z的最终评论相结合似乎是最好的解决方案。

使用以下代码段:

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

希望这可以帮助某人。


4

我知道我在这个话题中有点晚了。但是,这是我的答案,从Java 7起有效。

以下代码段

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

非常令人满意,因为如果文件不存在,则方法isRegularFile返回false。因此,无需检查Files.exists(...)

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

从Java Oracle文档


来自声纳文档:Files.exists方法在JDK 8中的性能明显较差,当用于检查实际上不存在的文件时,可能会严重降低应用程序的速度。 这同样适用Files.notExistsFiles.isDirectoryFiles.isRegularFile. 这最好的选择是:path.toFile().exists()
Genaut



2

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

 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

如果要检查File目录中的dir

String directoryPath = dir.getAbsolutePath()
boolean check = new File(new File(directoryPath), aFile.getName()).exists();

并检查check结果



1

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

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

可能不起作用,为什么不呢?以及使用URI如何解决此问题?
user207421 '18

我们有一个问题。f.exists()是正确的,我们甚至可以获取文件内容。问题是,路径错误,但是文件名正确,即使这是另一个文件。使用URI更改构造函数调用可解决此问题。
iviorel

1

File.exists()检查文件是否存在,它将返回一个布尔值以指示检查操作状态;如果文件存在,则为true;否则为false。如果不存在,则返回false。

File f = new File("c:\\test.txt");

if(f.exists()){
    System.out.println("File existed");
}else{
    System.out.println("File not found!");
}

0

您可以使用以下代码进行检查:

import java.io.File;
class Test{
    public static void main(String[] args){
        File f = new File(args[0]); //file name will be entered by user at runtime
        System.out.println(f.exists()); //will print "true" if the file name given by user exists, false otherwise

        if(f.exists())
        {
             //executable code;
        }
    }
}


0

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.