【问题标题】:Cannot delete zip file after unzipping?解压后无法删除zip文件?
【发布时间】:2013-06-03 18:26:00
【问题描述】:

我遇到了一个不寻常的问题。我正在构建一个计划每 5 分钟运行一次的工具。 它将从特定目录中提取 zip 文件并将文件(取决于文件名)提取到目标位置。我正在使用zipentry 获取 zip 文件中的每个文件名,然后根据需要进行提取,然后将它们(zip 文件,一旦我完成 zip 中的所有文件)备份到特定目录,然后删除 zip 文件。但有时(并非总是)zip 文件不会被删除。因为我使用的是fileutils.forcedelete()。我遇到了一个异常:无法删除文件。所以我将代码更改为使用fileutils.forcedeleteonexit() 仍然有一些文件保留在源代码中。

这是我的代码示例:

sourceFile=new file(zipfile);
zipFile = new ZipFile(sourceFile);
zEnum = (Enumeration<ZipEntry>) zipFile.entries();
for (int a = 0; a < zipFile.size(); a++)
{
  ZipEntry zE = zEnum.nextElement();
  //Function uses zip4j for extracting. No streams used.
  extract(String sourceZipFile, String fileNameToExtract, String outputFolder);
}
//I tried it with finally either
zipFile.close();

//Using fileutils to copy. No streams used.
copyFile(sourceFile, backup);

FileUtils.forceDeleteOnExit(sourceFile);

没有使用流,但我有时会锁定文件(并非总是如此)。 这里的错误似乎是什么?是导致问题的 zip4j 提取还是其他原因?我正在使用 zip4j 1.3.1。

【问题讨论】:

  • 什么操作系统? Windows 在文件句柄和删除方面存在臭名昭著的问题...
  • @fge:Windows.tried 在我的本地和服务器上(windows server 2008 R2)
  • @fge 在提取数据后尝试删除存档时,我无法说出多少次 Windows 告诉我“文件正在使用”,但肯定比我能指望的次数要多手。是程序没有正确关闭其文件句柄的错,还是 Windows 在程序关闭后仍保持某些文件打开?
  • 即使这样也应该有解决方法。Windows 中的admin 是什么意思
  • 所有文件都不能删除,还是部分文件不能删除?

标签: java unzip fileutils


【解决方案1】:

我认为您的问题与操作系统文件缓冲区有关,有时在您尝试删除文件时不会刷新。 您是否尝试使用 sourceFile.deleteOnExit() 而不是 FileUtils.forceDeleteOnExit(sourceFile)? 您也可以尝试在删除之前检查 sourceFile.canWrite (可能会有所帮助) 您也可以尝试在删除前使用 FileInputStream():

FileInputStream fi = new FileInputStream(sourceFile);
fi.getFD().sync();

【讨论】:

  • 我尝试使用 deleteOnExit() 也同样的问题退出。我没有使用任何 FileInputStream 因为我认为它可能是杯子
  • sourFile.canwrite 总是返回真!!
【解决方案2】:

使用 apache-commons IO 的 FileDeleteStrategy。比如:

FileDeleteStrategy.FORCE.delete(file);

更新

这应该是您的应用程序中处理 IO 的方式。我编写了简单的代码,将 zip 文件复制到临时 zip,将临时 zip 放气,几秒钟后将其删除。给你:

public class ZipTest {

private static String dirPath = "/home/ubuntuuser/Desktop/";

public static void main(String[] args) throws Exception {

    File myzip = new File(dirPath + "content.zip");
    String tempFileStr = dirPath + "content_temp.zip";
    File tempFile = new File(tempFileStr);
    String unzipFolderStr = dirPath + "unzip";


    copyUsingChannels(myzip, tempFile);

    // copyUsingStreams(myzip, tempFile);

    unZip(tempFileStr, unzipFolderStr);

    Thread.sleep(3000);

    tempFile.delete();


}

private static void copyUsingStreams(File myzip, File tempFile)
        throws IOException, FileNotFoundException {
    byte[] barray = new byte[1024];

    if (!tempFile.exists())
    {
        tempFile.createNewFile();
    }

    FileOutputStream fos = new FileOutputStream(tempFile);
    FileInputStream fis = new FileInputStream(myzip);

    int length = 0;

    while ((length = fis.read(barray)) != -1)
    {
        fos.write(barray, 0, length);
    }

    fis.close();
    fos.close();
}

public static void copyUsingChannels(final File srcFile, final File destFile) throws Exception
{
    if (!destFile.exists())
    {
        destFile.createNewFile();
    }

    FileChannel source = new FileInputStream(srcFile).getChannel();
    FileChannel destination = new FileOutputStream(destFile).getChannel();

    source.transferTo(0, source.size(), destination);

    source.close();
    destination.close();
}

private static void unZip(String zipFile, String outputFolder) throws Exception {

    byte[] buffer = new byte[1024];

    File folder = new File(outputFolder);
    if (!folder.exists()) {
        folder.mkdir();
    }

    ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));
    ZipEntry ze = zis.getNextEntry();

    while (ze != null) {

        String fileName = ze.getName();

        File newFile = new File(outputFolder + File.separator + fileName);

        System.out.println("file unzip : " + newFile.getAbsoluteFile());

        new File(newFile.getParent()).mkdirs();

        if (ze.isDirectory())
        {
            newFile.mkdir();
            ze = zis.getNextEntry();
            continue;
        }

        FileOutputStream fos = new FileOutputStream(newFile);

        int len;
        while ((len = zis.read(buffer)) > 0) {
            fos.write(buffer, 0, len);
        }

        fos.close();
        ze = zis.getNextEntry();
    }

    zis.closeEntry();
    zis.close();
}

}

【讨论】:

  • 同样的问题:无法删除文件!
  • 你能确认这不是因为上面的copy删除还在进行中吗?
  • @Chris.how 我可以检查一下。如果可以的话,我可以在复制完成后编码删除。
  • 更新了答案。请检查
猜你喜欢
  • 1970-01-01
  • 2016-05-02
  • 2022-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-30
相关资源
最近更新 更多