Zip file still open after zipping(VB)

Nov 7, 2010 at 10:21 PM

I hope this is a DotNetZip question. I use the following code to create a zip file. There are some images in d:/upload/tom

 

Dim DirectoryPath As String = "d:\upload\tom"

 

If My.Computer.FileSystem.DirectoryExists("d:/upload/tom") Then
            Using zip As New ZipFile
                zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath))
                zip.Comment = "This zip includes pictures for test"
                zip.AddEntry("Readme.txt", "This is the images for this application.")
                zip.Save("D:\attachments\images.zip")
            End Using

End If

Later  I have this code to delete the file:

If My.Computer.FileSystem.FileExists("D:/attachments/images.zip") Then

        Kill("D:\attachments\tradeinimages.zip")

End If

It gives me the debug error "...because it is being used by another process.".

Is there a way to release the zip file so I can delete it? This code is running from a test web server (Visual Web Developer 2010) if that makes any difference.

Nov 8, 2010 at 2:11 AM

I have a similar issue.  That is, after extracting all files from a SPLIT archive, I would like to be able to delete the source zip file(s).  I can successfully delete the segments .z01 .z02 .z03 etc, but, like your example, the final .zip cannot be deleted (... because the file is being used by another process).

The underlying issue is that somewhere there is a file and/or stream that is not being .Close() and is instead just "left hanging" because it still has some internal reference (which I have not found yet).

So, without fully studying/understanding the entire issue, and how this area of the code is supposed to work, I have a VERY-UGLY HACK-FIX that has worked for us.  I certainly DO NOT propose this as a final fix, and in our implementation have wrapped the following code sample with additional checks to ensure that this code is only enabled/run under the exact conditions described above ... and then our application exits very soon thereafter.

In the ZipFile.cs file, in the private Dispose() method, after the "if" statement (something cleaning up ParallelDeflator), approx line 3244, you can add code something like:

if (_entries.Values != null)
{
    foreach (var zfe in _entries.Values)
    {
        if (zfe.ArchiveStream != null)
        {
            zfe.ArchiveStream.Close();
        }
    }
}

This will close all the streams that are used, without concern as to where they came from.  Note this also breaks several Unit Tests, so "user beware".  I have not studied the whole problem in enough detail (and understanding) to be able to provide a "real fix".  I need some help here ...

Coordinator
Nov 10, 2010 at 2:25 AM

Lord, it's a DotNetZip question. Usually when people have this problem, it means they are reading or writing the zip file without the Using clause. Is there any other place in your code where you create a ZipFile object without the Using clause?  If so, this could cause the file to remain open. The fix is, obviously, to create the ZipFile object within a Using clause.

Also - There's a bit of confusion in the code you showed - you test for existence of images.zip, and then you Kill a file called tradeinimages.zip . Not sure if that is a problem in transcribing the code, or if there is actually an inconsistency in your code. 

To diagnose the problem you could try to delete the file immediately after creating it.  Because you have the using clause, the zip file should be deleteable at that moment.  If, somewhere else in the code, you read the file without a Using clause, it will then be held open, which will block the Kill() from succeeding. 

Let me know.

Coordinator
Nov 10, 2010 at 2:27 AM

Ripetomato, yes there is a problem in DotNetZip in the handling of segmented files. 

There's already a workitem logged for this;  I'm working on getting a build machine in order to test the fix and deliver a new release.