Java的File.delete()方法无法删除所有文件。

4

我有以下Java代码,它遍历目录中的所有文件并删除它们。

for(File file : tmpDir.listFiles())
{
    file.delete();
}

但是它并不能删除所有文件。通常在几千个文件中留下了20-30个文件,当我这样做时。有可能修复这个问题吗?或者我碰巧遇到了一些应该被放置的Java voodoo?


2
也许您没有删除文件的权限。或者它被锁定,或者重新创建了,或者发生了其他情况。检查返回值以了解删除是否成功。还要考虑到目录必须为空才能被删除。 - Stefano Sanfilippo
1
你确定你可以手动删除所有文件吗?有些可能正在被其他程序使用。尝试捕获异常:"请注意,Files类定义了删除方法,以便在无法删除文件时抛出IOException。这对于错误报告和诊断文件无法删除的原因非常有用。" - Alexis C.
1
请确保您要删除的文件没有打开的文件处理程序。 - Aakash
不,我有所有的权限。这是一组我生成、进行一些处理并再次删除的文件。但是有些文件“留下来”了,没有和它们的同类一起被删除。 - user1049697
@ZouZou 在Java 1.6中不会抛出任何异常,也许OP正在使用旧的JDK。 - Stefano Sanfilippo
显示剩余3条评论
3个回答

11

它返回一个布尔值,你应该检查一下。从JavaDoc中得知:

返回: 如果文件或目录成功删除,则为 true;否则为 false。

你应该检查返回值并进行相应的操作。

如果返回值为false,那么可能是因为你没有权限删除该文件。

在这种情况下,你可以检查应用程序是否有可写入该文件的权限,如果没有,尝试使文件可写入 - 这也会返回一个boolean值。如果成功,你可以再次尝试删除。

你可以使用一个实用方法:

private void deleteFile(final File f) throws IOException {
    if (f.delete()) {
        return;
    }
    if (!f.canWrite() && !f.setWritable(true)) {
        throw new IOException("No write permissions on file '" + f + "' and cannot set writeable.");
    }
    if (!f.delete()) {
        throw new IOException("Failed to delete file '" + f + "' even after setting writeable; file may be locked.");
    }
}

我也会在JavaDoc中接受他们的建议:

请注意,Files类定义了delete方法在无法删除文件时抛出IOException异常。这对于错误报告和诊断文件无法删除的原因非常有用。

前提是您使用的是Java 7。该方法会抛出多个异常,您可以处理:

try {
    Files.delete(path);
} catch (NoSuchFileException x) {
    System.err.format("%s: no such" + " file or directory%n", path);
} catch (DirectoryNotEmptyException x) {
    System.err.format("%s not empty%n", path);
} catch (IOException x) {
    // File permission problems are caught here.
    System.err.println(x);
}

这个例子摘自Oracle教程页面


1
我不明白为什么人们会给这个点赞。它没有回答提问者的问题,更适合作为评论。 - Stefano Sanfilippo
大约到达一半 - clwhisk
1
我尝试过这个,但它从未返回false,因此在删除文件时没有“错误”。当循环迭代并删除它们时,似乎无法看到这些文件。 - user1049697
你尝试过将迭代的文件名打印到记录器中,然后搜索有问题的文件吗?你尝试在删除调用之后添加断点,看看文件是否被其他东西重新创建了吗? - Boris the Spider
@BoristheSpider,我找到了错误。在删除文件之前运行“System.gc();”可以使文件可删除。 - user1049697
显示剩余5条评论

3
使用System.gc();强制垃圾回收使所有文件都可以被删除。

1
这是一个解决方案,但这样做“可以”吗? - Mafro34
1
我曾经遇到过这个问题,直到我发现了我忘记关闭的文件。通常情况下,如果我发现我必须收集垃圾才能获得所需的行为,则会发生资源泄漏。 - Jeff Learman
但是调用 System.gc(); 并不能保证垃圾回收会立即发生。 - Sreekanth Karumanaghat

0
确保您没有任何打开的流,如BufferedReader/Writer、FileReader/Writer等。首先关闭它们,然后您应该能够删除文件。 另外一个要点,例如,如果您通过另一个阅读器(比如FileReader)打开了一个BufferedReader,您必须单独关闭这两个阅读器。
所以,不要这样做:
BufferedReader reader = new BufferedReader(new FileReader(new File(filePath)););

做这个:

BufferedReader bufferedReader = null;
FileReader fileReader = null;

try{
    fileReader = new FileReader(readFile);
    bufferedReader = new BufferedReader(fileReader);

}catch{...}

...

try {
    fileReader.close();
    bufferedReader .close();
    readFile.delete();
} catch (IOException e) {
    e.printStackTrace();
}

这是错误的,看这里:我需要关闭FileReader和BufferedReader吗? - Max Vollmer

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