【问题标题】:How to remove temporary files on windows?如何删除windows上的临时文件?
【发布时间】:2020-01-09 06:08:10
【问题描述】:

在某个地方我创建了临时文件:

Files.createTempDirectory("chunk");

在处理后的其他地方,我尝试删除文件:

Files.deleteIfExists(somePath) 

并体验以下跟踪:

java.nio.file.FileSystemException: C:\....\Temp\chunk11607697185854596263\chunk-3.csv: The process cannot access the file because it is being used by another process.
    at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:92)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
        at java.base/sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:270)
        at java.base/sun.nio.fs.AbstractFileSystemProvider.deleteIfExists(AbstractFileSystemProvider.java:110)
        at java.base/java.nio.file.Files.deleteIfExists(Files.java:1180)
        at my.some.project.batch.MyClass.afterStep(MyClass.java:31)

当我在本地 Windows 机器上启动应用程序时会发生这种情况,而在 docker 中不会发生这种情况。当我在 MacOS 上本地运行应用程序时,我也不会遇到此类错误。什么问题,我该如何解决?

【问题讨论】:

  • 检查哪个进程用Process Explorer打开了文件。也许您已经用记事本或其他工具打开了文件以检查文件而不是关闭它?
  • 确保您的代码正在关闭所有 InputStreams、OutputStreams、Readers 和 Writers。
  • @VGR 我提供了所有与 IO 相关的代码
  • 当我重新阅读您的问题时,您的错误消息和您对您正在做什么的解释与您的代码不符。你创建一个目录,做一些事情,然后删除......究竟是什么? somePathcreateTempDirectory返回的路径吗?要删除目录,该目录必须为空。但是,错误消息指向该目录中的文件。你能创建一个Minimal, reproducable example 吗?要么你自己发现错误,要么让我们更容易理解发生了什么。
  • “所有与IO相关的代码”?您是说没有其他代码行可以使用您创建的临时目录吗?如果是这样,为什么要首先创建它?

标签: java windows io nio


【解决方案1】:

检查文件是否未被其他进程打开。可以使用Process Explorer 完成此检查。启动程序后,在菜单中选择Find,然后选择Find Handle or DLL...,或按Ctrl+F。输入被某个进程锁定的文件名,点击Search

Windows 和类 Unix 操作系统在处理已打开文件的删除方面存在差异。

在类 Unix 系统上,即使文件已被其他进程打开,也可以删除该文件。在所有其他进程关闭文件之前,不会删除实际文件,但会删除文件系统上的文件名条目。只要操作的第一部分成功,低级文件删除操作就会返回成功。实际文件数据的删除会延迟到打开计数达到 0。

在 Windows 上,任何进程都不能打开该文件,以使低级文件删除操作能够成功。

这可能是您在 Windows 与 Docker 或 MacOS 上运行程序时看到不同行为的原因。

【讨论】:

  • 您能解释一下如何使用您建议的工具找到保存文件的进程吗?
  • 实际上我在同一个进程中创建和删除文件
  • 但是它是否也被某些外部进程打开了?或者,正如@VGR 在对您上述问题的评论中所建议的那样,您是否关闭了您用于写作和/或阅读的所有类型的流?
  • 其他外部进程对这些文件一无所知
  • 在我开始在你的工具中搜索后 - 我的电脑开始工作非常缓慢
【解决方案2】:

在 Windows 中使用 Java 删除文件时存在很多问题。最重要的是在尝试删除文件之前确实确保没有未关闭的流,因为 VGR 已经提到过。

有关常见问题的更多信息,您可以查看以下内容: delete & GC 还有这个:file delete

我正在使用这种看起来很糟糕的“解决方案”来删除文件,请随意尝试:

public static boolean deleteFile(File file)
        throws Exception {
    if (!file.exists()) {
        throw new Exception("File not found: " + file.getName());
    }
    try {
        file.setWritable(true);
    } catch (Exception ignored) {
    }
    int delay = 50;
    for (int i = 0; i < 20; i++) {
        if (file.delete()) {
            return true;
        }
        System.gc();
        try {
            Thread.sleep(delay);
        } catch (InterruptedException ignored) {
        }
        delay = delay + 50;
    }
    throw new Exception("Could not delete the file '"
            + file.getName() + "'");
}

【讨论】:

  • 不幸的是,它没有帮助我
猜你喜欢
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-20
相关资源
最近更新 更多