Java 无法删除临时文件夹(有时)

Java 无法删除临时文件夹(有时),java,io,Java,Io,启动应用程序时,我会创建一个临时文件夹: public static File createTempDir(String name) throws IOException { File tempDir = File.createTempFile(name, ""); if (!(tempDir.delete())) { throw new IOException("could not delete" + tempDir.getAbsolutePath());

启动应用程序时,我会创建一个临时文件夹:

  public static File createTempDir(String name) throws IOException {
    File tempDir = File.createTempFile(name, "");
    if (!(tempDir.delete())) {
      throw new IOException("could not delete" + tempDir.getAbsolutePath());
    }

    if (!(tempDir.mkdir())) {
      throw new IOException("could not create" + tempDir.getAbsolutePath());
    }
    tempDir.deleteOnExit();
    return tempDir;
  }
在会话期间,用户可能会加载文件。因此,将删除旧的temp dir,并根据加载文件的ID创建新的temp dir

在删除旧临时目录的加载过程中,我有时会收到:

java.io.IOException:无法删除文件:

以下是如何删除旧的临时文件夹:

  public void cleanup(String tmpPath) {
    File tmpFolder = new File(tmpPath);
    if (tmpFolder != null && tmpFolder.isDirectory()) {
      try {
        FileUtils.deleteDirectory(file);
      } catch (IOException e) {
            e.printStackTrace();
      }
    } 
  }
其中FileUtils是:org.apache.commons.io.FileUtils。临时文件夹的内容通常为:

mytempfolder_uuid |->我的子文件夹 |->myImage.jpg

错误是:

java.io.IOException:无法删除文件:C:\Users\xxx\AppData\Local\Temp\mytempfolder\u uuid\mysubfolder\myImage.jpg

我已尝试调试该应用程序,并在执行删除操作之前验证上述图像是否实际位于指定文件夹中


令人讨厌的是,这只是偶尔发生。我已确保不会在任何其他应用程序中打开临时文件夹中的文件夹/文件。有什么想法/建议吗?

您不能删除打开的文件,也不能删除包含文件的目录。您必须确保目录中的所有文件都已关闭。

我建议您使用Guava库。它有一种方法可以完全满足您的需求:

以原子方式在系统目录下的某个位置创建一个新目录 临时目录(由java.io.tmpdir系统定义 属性),并返回其名称。使用此方法而不是 创建临时文件(字符串,字符串) 目录,而不是常规文件一个常见的陷阱是调用 createTempFile,删除该文件并在其位置创建目录, 但这导致了一种可以利用的竞赛条件 安全漏洞,尤其是当要删除可执行文件时 写入目录。此方法假定 卷是可写的,具有空闲索引节点和空闲块,并且它将 每秒不会被调用数千次


在删除临时文件夹之前,请尝试删除该文件夹中的文件。试试像这样的东西

private boolean deleteFolder(File path) {
    if (path.exists()) {
        File[] files = path.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                deleteFolder(f);
            } else {
                f.delete();
            }
        }
    }

    return path.delete();
}
另外,使用deleteOnExit也不是一个好主意

干杯

public static boolean deleteDir(String path)
{
    java.io.File dir = new java.io.File(path);
    if (dir.isDirectory())
    {
        String[] filesList = dir.list();
        for(String s : filesList)
        {
            boolean success = new java.io.File(dir, s).delete();
            if(!success)
            {
                return false;
            }
        }
    }
    return dir.delete();
}

然后你可以像这样使用它:
deleteDir(“C:\\MyFolder\\subFolder\\”

也许你忘了关闭应用程序中某个文件的流?也许有人(用户,应用程序)在你尝试删除时有时会使用该文件夹。@tul,你有将近30个问题没有被接受的答案。也许你可以试着问一些可以合理回答的问题,或者跟进答案,以便他们能够被接受但这正是org.apache.commons.io.FileUtils.deleteDirectory(文件)所做的。我需要deleteOnExit,因为我不希望temp dir变得异常大-您还将如何执行清理?deleteOnExit不会帮助您将temp dir保持在最小大小。如果您想这样做,您可以编写一个简单的线程来监视dirs大小,并在大小超过某个阈值时将其删除。或者,如果您使用的是apache commons,您可以安装一个FileMonitor来监视目录。。。使用deleteOnExit是不好的,因为它会泄漏内存,并且不能保证它会成功。是的,deleteOnExit似乎只适用于空文件夹:-(据我所知,org.apache.commons.io.FileUtils.deleteDirectory(文件)递归删除文件夹。是否可以从java代码中获取引用特定文件/文件夹的进程列表?您可以在Unix中使用
lsof
。打开文件的很可能是您的进程。尤其是临时文件。我相信这基本上就是org.apache.commons.io.FileUtils.deleteDirectory(文件)有。好的,谢谢你的提示,我会尝试一下!我真的需要这是确定的。目前,它只在有时有效,即使我通过完全相同的步骤(保存/加载相同的文件夹/文件)似乎非常随机。好的,我尝试过用番石榴替换我的实现,但我的问题仍然存在。出于某种原因,一个文件(image.jpg)在我运行测试时,temp dir中的一半不能被删除,另一半可以正常工作。必须是某些资源在删除之前没有正确处理它。@tul是的,请确保关闭所有流(输入和输出)在finally blocks中。您可能想查看一下。基本上,我只是在一个按钮上设置了org.eclipse.swt.graphics.Image.Image,比如:myImage=newimage(getDisplay(),newimagedata(absolutePath));button.setImage(myImage);在进行加载之前,我确保容器小部件已关闭,并且所有子小部件/图像都已处理。但仍然困扰我的是,它只有50%的几率发生。@tul无法帮助您进行SWT。您应该用SWT标记在另一个问题中询问该部分