ChatGPT解决这个技术问题 Extra ChatGPT

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

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

唯一的 similar question on SO 处理写入文件,因此使用 FileWriter 回答,这显然不适用于此处。

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

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

D
DVK

使用 java.io.File

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

在某些情况下,exists() 会返回不正确的结果。例如,当使用 NFS 文件系统时,会出现文件句柄过时的问题:bugs.java.com/bugdatabase/view_bug.do?bug_id=5003595 这有点晦涩难懂,但之前在生产代码中一直是一些令人沮丧的错误的原因。
请改用 if(f.isFile())
记得使用 filePathString.trim() 来避免空格
为了澄清 @Leon 的响应,如果 f 是一个目录或者它不存在,则 f.isFile() 返回 false。因此,它(大部分)等价于 f.exists() && !f.isDirectory(),尽管后者更明确地表达了意图。
D
DVK

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

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

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


@ylun.ca 示例包含子目录?如果您要问,如果当前目录为 /path,如果正确的完整路径是 /path/to/file.txtnew File("file.txt").exists() 是否会返回 true,答案是否定的(除非存在另一个文件 /path/file.txt)。
k
kc2001

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


与 new File(path).exists() 相比有什么优势?对于 palin 存在检查
@RaghuKNair java.nio.file.Files.exists()java.io.File.exists()很多(来自我在我测试的唯一计算机上的小基准测试:运行 Java 1.7.0_45 x64 的 Windows Server 2012)。
我自己试了一下,java.nio.file.Files.exists()java.io.File.existsSLOWER 5 倍。 (Win7 Java 1.7.0_79 - x86)
这也有一个缺点,如果字符串无效,Paths.get 会抛出异常
W
Wendel

使用 Java 8:

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

Files.exists() 有两个参数。通常,您需要类似 Files.exists(path, LinkOption.NOFOLLOW_LINKS ) 的内容。
@MikeC我想知道没有第二个参数会调用哪个方法。 Docu 甚至没有显示任何相关信息。
@PowerFlower:只有一个 Files.exists() 方法。不传递第二个参数,它仍然调用相同的方法。第二个参数是 varargs 变量,可以传递 0 个或多个 LinkOptions。
与之前的答案重复。
S
Soner Gönül
File f = new File(filePathString); 

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

f.createNewFile();

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


j
jhumble
f.isFile() && f.canRead()

Pearl 的 -e 是否也确保应用程序“可以读取”文件?
m
m00am

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

如果只是为了存在。它可以是文件或目录。 new File("/path/to/file").exists();检查文件 File f = new File("/path/to/file"); if(f.exists() && f.isFile()) {} 检查目录。文件 f = new File("/path/to/file"); if(f.exists() && f.isDirectory()) {} Java 7 方式。路径 path = Paths.get("/path/to/file"); Files.exists(path) // 存在 Files.isDirectory(path) // 是目录 Files.isRegularFile(path) // 常规文件 Files.isSymbolicLink(path) // 符号链接


u
user207421

不。只需捕捉 FileNotFoundException. 文件系统必须测试文件是否存在。这样做两次是没有意义的,并且有几个原因不这样做,例如:

加倍代码

时间窗口问题,即文件可能在您测试时存在但在您打开时不存在,反之亦然,以及

事实上,正如这个问题的存在所表明的那样,您可能会进行错误的测试并得到错误的答案。

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


如果我想每小时检查一次以查看文件是否已直接存放在某个位置怎么办。我有一个 webMethods 项目,它必须检查特定文件是否已上传到特定驱动器。这将如何完成。假设我想每小时检查一次以查看文件是否存在。我可以使用 Java 编写一个类,它可能使用某种计时器来执行此操作。
捕获异常的成本要高得多。在我的测试中,检查 new File().exists() 比捕获 FileNotFoundException 快 10 倍以上。因此,如果您遇到通常预期会丢失文件的情况(例如磁盘缓存),则异常是错误的。此外,事后猜测系统很酷。
@Gnawer 你还没有解决我提出的任何问题;仅当文件无法打开时才抛出异常;每小时发生一次的操作不需要微优化。你的最后一句话是胡说八道。
@DougHauf 在您的情况下没有问题,因为您在检查存在后不尝试做任何事情。但是OP专门要求在打开前检查。在这种情况下,最好尝试/捕获打开的文件。
b
blackpanther

您可以使用以下内容:File.exists()


b
blackpanther

在谷歌上首次点击“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 "));
    }
}

在检查 f.exists 之前无需检查是否 f != null,如果新关键字失败,它将生成异常。
没有检查是否 f != null。 f + (...) 使用 java.io.File.toString
@just 实际上,它使用 String.valueOf(),它处理空值
X
X-Fate

对我来说,将 Sean AO Harney 接受的答案和 Cort3z 的评论结合起来似乎是最好的解决方案。

使用了以下代码段:

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

希望这可以帮助某人。


a
avi.elkharrat

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

以下片段

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

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

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

From Java Oracle documentation


来自声纳文档:Files.exists 方法在 JDK 8 中的性能明显较差,并且在用于检查实际不存在的文件时会显着降低应用程序的速度。 Files.notExists 也是如此, Files.isDirectoryFiles.isRegularFile. 最好的替代方法是:path.toFile().exists()
p
peter.murray.rust

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


不回答问题的方式。我同意 commons 有很多有用的东西,但也许我们可以更进一步,为 OP 提出的问题提供答案。
他给了我足够的答案。
Apache Commons Libs 已经在大多数项目中使用的情况并不少见。我认为这个答案非常有帮助。在我最终开始使用 Apache Commons 之前,我数不清有多少次重新发明轮子。 +1 来自我
A
Amandeep Singh

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

 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


问题在于打开它是为了阅读,而不是为了写作,无论如何这肯定不是“好的编码实践”。
i
iviorel

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

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

可能不工作为什么不呢?以及如何使用 URI 解决这个问题?
我们遇到了一个问题。 f.exists() 是真的,我们甚至可以得到文件内容。问题是,路径错误但文件名没问题,即使这是另一个文件。使用 URI 更改构造函数调用,解决了问题。
难以置信。使用 URI 并将 \ 更改为 / 不会产生这种效果。您必须同时修复了其他东西。
c
codeepic

你可以这样做

import java.nio.file.Paths;

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

考虑到您的答案与 JDK 8 中的 File.is Exist()Files.isRegularFile() 相比具有最佳性能
A
Atul Jain

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

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


b
begum sakin

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


请提供一些代码。