Question

I've written a program that decompresses a ZIP archive, then recursively decompresses or extracts archives found in it. The archives within the ZIP may be tar or ZIP archives and I can extract them just fine.

After extracting the inner archives within some new directory, I want to delete them. This works just fine for tar archives, but for some reason it will not work for ZIP archives. I've closed all streams, and should deletion fail I use deleteOnExit as a fail-safe, but that doesn't work either.

    try (ArchiveInputStream ais =
         asFactory.createArchiveInputStream(
           new BufferedInputStream(
             new FileInputStream(archive)))) {

        System.out.println("Extracting!");
        ArchiveEntry ae;
        while ((ae = ais.getNextEntry()) != null) {
            if (ae.isDirectory()) {
                File dir = new File(archive.getParentFile(), ae.getName());
                dir.mkdirs();
                continue;
            }

            File f = new File(archive.getParentFile(), ae.getName());
            File parent = f.getParentFile();
            parent.mkdirs();
            try (OutputStream os = new FileOutputStream(f)) {
                IOUtils.copy(ais, os);
                os.close();
            } catch (IOException innerIoe) {
                ...
            }
        }

        ais.close();
        if (!archive.delete()) {
            System.out.printf("Could not remove archive %s%n",
                               archive.getName());
            archive.deleteOnExit();
        }
    } catch (IOException ioe) {
        ...
    }

There should be no open streams, unless closing the ArchiveInputStream doesn't actually close the stream. But again this works for tar archives.

I read somewhere that one can manage to delete ZIP archives calling listFiles() on the parent file and locating the ZIP archive and deleting it, but this sounds like a weird convoluted process. There must be some simpler way.

EDIT:

The problem is specific to Windows. On Linux (SliTaz 4 and Red Hat Enterprise 5) this works perfectly fine. This tells me that Windows is somehow locking the ZIP archives, which seems a bit strange.

Was it helpful?

Solution

Unfortunately it is quite common that files belonging to streams you have closed just now cannot be deleted on Windows. Sometimes you need to wait a little and sometimes even that is not enough and you need a garbage collection cycle.

For example this has lead to Ant's FileUtils#tryHardToDelete https://github.com/apache/ant/blob/master/src/main/org/apache/tools/ant/util/FileUtils.java#L1569 - and even that is known to sometimes leave files dangling, in which case File#deleteOnExec is your best bet.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top