Zip File is cleared out

Jul 19, 2011 at 3:37 PM

Hi

I'm using this library in a console app to zip up files on different network locations.  It works good everywhere except one particular location, which I can't explain.

The App is being run from a windows server 2003 system and is written in C# 2010 Express.  I have it setup so it will only zip files that are older than 5 days.  They are collected into a string collection and then I loop through and add to the zip file.  I've seen it work when I step through the code, but as an EXE it seems like it's not working properly.  Is it possible that I'm getting to the Delete file section before the zip.save finishes?  So I'm deleting the file I tried zipping before it's done zipping, and then it doesn't get into the zip file.   Is that possible?  Please let me know if anything stands out in my code that could be tweaked too (I'm kind of a C# newb)

 

 

List<String> contents, string pZipFile,bool storepath


            bool zipexists = false;
            Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile();
            if (File.Exists(pZipFile))
                zipexists = true;
            else
                zipexists = false;

            if (zipexists)
                zip = Ionic.Zip.ZipFile.Read(pZipFile);


            //using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile(pZipFile))
            using (zip)
            {
                
                zip.ZipError += MyZipError;
                zip.UseZip64WhenSaving = Zip64Option.AsNecessary;
                zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;
                zip.ZipErrorAction = ZipErrorAction.InvokeErrorEvent;
                foreach (string FileToZip in contents)
                {
                    try
                    {
                        if (storepath == true)
                            zip.UpdateFile(FileToZip);
                        else
                            zip.UpdateFile(FileToZip, "");
                        //zip.AddFile(FileToZip);
                    }
                    catch (Exception ex)
                    {
                        nlog.WriteLog("Error adding " + FileToZip + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace);
                        zip.Dispose();
                        return false;
                    }
                }
                try
                {
                    Console.WriteLine("Zipping " + pZipFile);
                    zip.Save(pZipFile);
                }
                catch (Exception ex)
                {
                    nlog.WriteLog("Error zipping file(s) into " + pZipFile + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace);
                    zip.Dispose();
                    return false;
                }
            }
            BatchError berror = new BatchError();
            Console.WriteLine("Deleting files");
            foreach (string FileToZip in contents)
            {
                try
                {
                    File.Delete(FileToZip);
                }
                catch (Exception ex)
                {
                    berror.AddError(FileToZip, ex.Message);
                    //nlog.WriteLog("Error deleting file: "+FileToZip+Environment.NewLine+ex.Message+Environment.NewLine+ex.StackTrace);
                }
            }
            if (berror.HasErrors)
            {
                nlog.WriteLog("Error Deleting File(s):" + Environment.NewLine + berror.GetErrorMessage());
                return false;
            }
            return true;

 

 

Coordinator
Jul 19, 2011 at 4:18 PM

I'll have a look and send you a response a little later. At first glance it appears that you are not taking advantage of the using clause as well as you could.

Coordinator
Jul 19, 2011 at 11:59 PM

Newb, this works for me:

        void MyZipError (object sender, Ionic.Zip.ZipErrorEventArgs e)
        {
            Console.WriteLine("Error!");
        }

        void MySaveProgress (object sender, Ionic.Zip.SaveProgressEventArgs e)
        {
            switch (e.EventType)
            {
                case ZipProgressEventType.Saving_Started:
                    Console.WriteLine("status saving started...");
                    break;

                case ZipProgressEventType.Saving_BeforeWriteEntry:
                    Console.WriteLine("Compressing {0}", e.CurrentEntry.FileName);
                    break;
                case ZipProgressEventType.Saving_Completed:
                    Console.WriteLine("status Save completed");
                    break;
            }
        }


        public bool Run()
        {
            CreateLinks();
            List<String> contents = new List<String>(Directory.GetFiles(subdir));
            string pZipFile = "newb.zip";
            bool storepath = true;

            try
            {
                // You can use the parameterized constructor for ZipFile,
                // regardless whether the file exists or not.  If it exists,
                // it will be read.  If it does not exist, it will be
                // created.
                using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile(pZipFile))
                {
                    zip.ZipError += MyZipError;
                    zip.SaveProgress += MySaveProgress;
                    zip.ZipErrorAction = ZipErrorAction.InvokeErrorEvent;
                    zip.UseZip64WhenSaving = Zip64Option.AsNecessary;
                    zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;

                    foreach (string fileToZip in contents)
                    {
                        Console.WriteLine("adding {0}", fileToZip);

                        if (storepath == true)
                            zip.UpdateFile(fileToZip);
                        else
                            zip.UpdateFile(fileToZip, "");
                    }

                    Console.WriteLine("Saving " + pZipFile);
                    zip.Save(pZipFile);
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine("Error zipping file(s) into " + pZipFile + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace);
                return false;
            }


            Console.WriteLine("Deleting files..");
            int nErrors = 0;
            foreach (string fileToZip in contents)
            {
                try
                {
                    File.Delete(fileToZip);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error deleting {0} : {1}",
                                      fileToZip, ex.Message);
                    nErrors++;
                }
            }
            if (nErrors > 0)
            {
                //Console.WriteLine("Error Deleting File(s):" + Environment.NewLine + berror.GetErrorMessage());
                return false;
            }
            Directory.Delete(subdir, true);
            return true;
        }

Some tips: You do not need a try..catch within the using clause. You do not need to explicitly call .Dispose() on the ZipFile instance - the using clause does it for you. You do not need to use 2 different ways to instantiate a ZipFile instance - you can use a single constructor whether the zip file exists or not.

I don't know why your code wasn't working, but it's better to use correct code, then try to debug, rather than debugging incorrect code.

Jul 20, 2011 at 2:58 PM

Thanks Cheeso!

 

I'm going to go through your code and make sure I understand what's going on and then try debugging that.