Unable to delete zip after extraction - file locked

Feb 18, 2009 at 12:51 PM
Edited Feb 18, 2009 at 12:54 PM
Hi,
Thanks for the last message and it seems to work wonderful. The last hurdle i have is that once i have extracted the file, i would like to delete the original zip file which seems to be locked by ZipFile for some reason. I have tried Dispose, and setting it as null but neither seems to work.

Please help.


Ionic.Zip.ZipFile zip = Ionic.Zip.ZipFile.Read(zipName);
//zip.ExtractProgress
zip.ExtractProgress += new EventHandler<ionic.zip.extractprogresseventargs>(zip_ExtractProgress);
zip.ExtractAll(targetDir, true);
zip.Dispose();
zip = null;

Coordinator
Feb 19, 2009 at 2:35 AM

Alag, I don't see in that code where you are trying to delete the file.  what do you mean by "seems to be locked."  What happens when you run your code?  Do you get an exception? where?

I coded up a test of my own that
 - creates a zip file
 - reads the file and extracts all entries
 - deletes the original zip file

My code works.  No exceptions. 

// CreateZipSimple.cs
// ------------------------------------------------------------------
//
// Test out create/read+Extract/delete of a zip file. 
// 
// Author: Dinoch
// built on host: DINOCH-2
// originally created Wed Feb 18 17:54:44 2009
//
// last saved: 
// Time-stamp: <2009-February-18 18:23:49>
// ------------------------------------------------------------------
//
// compile with:
// csc /debug+ /target:exe /r:Ionic..Zip.dll /out:CreateZipSimple.exe CreateZipSimple.cs 
//
//
// Copyright (c) 2008 by Dino Chiesa
// All rights reserved!
// 
//
// ------------------------------------------------------------------
using System;
using System.IO;
using Ionic.Zip;


namespace Ionic.Zip.Samples
{

    public class CreateZipSimple
    {
        // ctor
        public CreateZipSimple () {}

        // ctor
        public CreateZipSimple (string[] args)
        {
            for (int i=0; i < args.Length; i++)
            {
                switch (args[i])
                {
                default:
                    if (DirToZip != null)
                    {
                        Usage();
                        return;
                    }
                    DirToZip = args[i];
                    break;
                }
            }
        }

        string TargetDir = null;
        string ZipFileToCreate = null;
        string DirToZip = null;

        private void Setup()
        {
            if (DirToZip== null) { Usage(); System.Environment.Exit(1);}
            TargetDir = String.Format("unpack.{0}", System.Diagnostics.Process.GetCurrentProcess().Id);
            ZipFileToCreate = "CreateZipSimple.zip";
            RemoveZipFile();
        }


        private void RemoveDirectory()
        {
            Console.WriteLine("=======================================================");
            Console.WriteLine("deleting {0}...", TargetDir);
            if (Directory.Exists(TargetDir))
            {
                Directory.Delete(TargetDir, true);
            }
            else
                Console.WriteLine("directory '{0}' does not exist...", TargetDir);
        }



        private void RemoveZipFile()
        {
            Console.WriteLine("=======================================================");
            Console.WriteLine("deleting {0}...", ZipFileToCreate);
            if (File.Exists(ZipFileToCreate))
            {
                File.Delete(ZipFileToCreate);
            }
            else
                Console.WriteLine("file '{0}' does not exist...", ZipFileToCreate);
        }



        private void Run()
        {
            Setup();
            CreateZipFile();
            ReadZipFile();
            RemoveZipFile();
            RemoveDirectory();
        }
    

        private void CreateZipFile()
        {
            Console.WriteLine("=======================================================");
            Console.WriteLine("zipping dir '{0}' into zipfile '{1}'...", DirToZip, ZipFileToCreate);

            using (ZipFile zip = new ZipFile())
            {
                // note: this does not recurse directories!
String[] filenames = System.IO.Directory.GetFiles(DirToZip); foreach (String filename in filenames) { Console.WriteLine("Adding {0}...", filename); zip.AddFile(filename); } zip.Save(ZipFileToCreate); } } private void ReadZipFile() { Console.WriteLine("======================================================="); Console.WriteLine("Reading and Extracting zip '{0}' to directory {1}", ZipFileToCreate, TargetDir); Ionic.Zip.ZipFile zip = Ionic.Zip.ZipFile.Read(ZipFileToCreate); //zip.ExtractProgress += new EventHandler<ionic.zip.extractprogresseventargs>(zip_ExtractProgress);
zip.ExtractProgress += zip_ExtractProgress; zip.ExtractAll(TargetDir, true); zip.Dispose(); zip = null; Console.WriteLine(); } bool firstReport = true; public void zip_ExtractProgress(object sender, ExtractProgressEventArgs e) { if (firstReport) Console.Write("Extract"); Console.Write("."); firstReport= false; } public static void Usage() { Console.WriteLine("CreateZipSimple: test bed for creating zip files.\n"); Console.WriteLine("Usage:\n CreateZipSimple <DirToZip> "); } public static void Main(string[] args) { try { CreateZipSimple me = new CreateZipSimple(args); me.Run(); } catch (System.Exception exc1) { Console.WriteLine("Exception: {0}", exc1.ToString()); Usage(); } } } }
Feb 19, 2009 at 9:45 AM
Edited Feb 19, 2009 at 2:07 PM
Hi Cheeso,
Sorry I didn't realize that i missed the code snippet above. I have the last line as File.Delete(zipName) which throws an exception that says file is currently in use and hence cannot be deleted.

I can try your code again - but that will be in a few hours as i am off to a few meetings as of now:)

Update
----------
Thanks for your help and i upgrade to latest 1.7 as per your comments in the other thread but that still seems to have the same issue

This has now been resolved - Thank you.
Feb 20, 2009 at 12:40 AM
Getting the same issue but with a file move command, actually.

ZipFile zip = new ZipFile(downloadedFile);
                    foreach (ZipEntry entry in zip)
                    {
                        if (regexCSV.IsMatch(entry.FileName))
                        {
                            ImportData(new StreamReader(entry.OpenReader()));
                        }
                    }

try
                    {
                        File.Move(downloadedFile, @"processed\" + Path.GetFileName(downloadedFile) + DateTime.Now.ToFileTime().ToString());
                    }
                    catch (System.IO.IOException ioError)
{
}

I've verified that the stream is being closed, but it still throws an IOException saying the file is still in use.
                    {
                        Console.WriteLine("Couldn't copy file to processed folder. File already exists there!");
                    }



Feb 20, 2009 at 12:47 AM
Actually using "using()" fixes it. Thanks.
Feb 20, 2009 at 8:53 AM
For others who are having similar problem, you can also add zip.dispose(); zip= null; which unlocks the file if you dont want to use "using()".
Apr 17, 2009 at 3:28 AM
Hi all,
I have the same issue under ".NET Compact Framework 2.0 ( Windows Mobile ) ". however the code have no problem under "Full Framework ( Windows ).

if (File.Exists(zippath))
{
    try
    {
        using (Ionic.Zip.ZipFile f = new Ionic.Zip.ZipFile(path))
        {
            f.ExtractAll(targetDir, true);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }

    try
    {
        File.Delete(path);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}



Apr 17, 2009 at 10:45 AM
+1
Apr 17, 2009 at 10:52 AM
+1? What's?
Coordinator
Apr 19, 2009 at 4:49 PM
I think what he is saying is, "I also have this problem on the .NET CF".

I recognize this is a problem, with the DotNetZip library on .NET CF.   
I've been in the process of moving out of my house, and so unable to look into this problem.
I will get to work on it as soon as possible. 
I'll let you all know what I find.
Apr 20, 2009 at 8:32 AM
yes,sorry, uaually when in a forum you post "+1" that means that you agree with the commentary inmediatly above you without posting innecesary words.
Apr 21, 2009 at 4:52 PM
I've found a solution to this problem, well not a "real" solution, only a circunvent

instead of uncompressing the file directly using somethig similar to this....

      ZipFile zip = ZipFile.Read(myZipfile);
      foreach (ZipEntry e in zip)
      {
               e.Extract(path);
        }
        zip.Dispose();
        zip = null;

use instead


             FileStream fs2 = new FileStream(myZipfile, FileMode.Open);
            byte[] stream= new byte[fs2.Length];
            fs2.Read(stream, 0, (int)fs2.Length);
            fs2.Close();

and then

      ZipFile zip = ZipFile.Read(stream);

      foreach (ZipEntry e in zip)
      {
               e.Extract(path);
        }
        zip.Dispose();
        zip = null;


and then u magically can delete the file myZipfile

u can use using() if you prefer.

Note that this is not a real solution, only a way to keep the library working while Cheeso finds the real solution . Hope this workaroung helps to find the real problem












Apr 22, 2009 at 1:17 PM
Thanks a lot!!!
I can delete the zip file after extracting.
Coordinator
Apr 28, 2009 at 6:42 PM
Thanks for the tip.  I still have to find a real solution.
Coordinator
May 1, 2009 at 1:39 AM
I believe this is now fixed in the DotNetZip library for .NET CF.
If you are on v1.7, you need v1.7.2.16. 
If you are on v1.8, you need v1.8.2.11. 

Let me know if it is not fixed!
May 4, 2009 at 9:32 AM
Seems to work fine in v1.7.2.16.

Thanks
May 21, 2009 at 10:28 AM

Thanks - this works in 1.7.2.16 onwards.