5

I am facing an unusal issue.I am building a tool which is scheduled to run every 5 mins. It will pick up the zip files from a particular directory and extract files (depending on the file name) to a destination. I am using zipentry to get each filename in zip file and then extracting as required then I back them (zip files, once I finish all the files in a zip) to a particular directory and then delete the zip file. But sometimes (not always) the zip files do not get deleted. Since I am using fileutils.forcedelete(). I am getting an exception: unable to delete file. So I changed to the code to using fileutils.forcedeleteonexit() still some files remain in the source.

Here is a sample of my code:

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);

There are no streams used but I am getting a lock on files sometimes (not always). What seems to be the bug here? Is it the zip4j extraction that is causing the problem or anything else? I am using zip4j 1.3.1.

2 Answers2

0

Use apache-commons IO's FileDeleteStrategy. Something like:

FileDeleteStrategy.FORCE.delete(file);

Update:

It should be the way IO is being handled in your application. I have written simple code which copies a zip file to a temporary zip, deflates the temporary zip and after few seconds deletes it. Here you go:

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();
}

}
Chris
  • 5,346
  • 7
  • 35
  • 56
0

I think your problem related with OS file buffers, that sometimes are not flushed when you are trying to delete file. Did you try to use sourceFile.deleteOnExit() instead FileUtils.forceDeleteOnExit(sourceFile)? Also you can try to check sourceFile.canWrite before deleting (may be it may helps) You can also try to use FileInputStream() before deleting:

FileInputStream fi = new FileInputStream(sourceFile);
fi.getFD().sync();
Denis Zaikin
  • 509
  • 4
  • 9