This project is read-only.

ZipFile.Save() fails when there is no root level file

Mar 26, 2008 at 5:33 PM
If I build a directory that contains only subdirectories and no top level files, such as:


I get the following exception when calling Save("C:\zipme\") on the ZipFile instance.

System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Ionic.Utils.Zip.ZipEntry.WriteHeader(Stream s, Byte[] bytes) in C:\SourceCode\Branches\MCC MLMv2\Library Projects\Ionic.Utils.Zip\ZipEntry.cs:line 852
at Ionic.Utils.Zip.ZipEntry.Write(Stream s) in C:\SourceCode\Branches\MCC MLMv2\Library Projects\Ionic.Utils.Zip\ZipEntry.cs:line 928
at Ionic.Utils.Zip.ZipFile.Save() in C:\SourceCode\Branches\MCC MLMv2\Library Projects\Ionic.Utils.Zip\ZipFile.cs:line 739

But if I include an actual file at the root level:


everything works fine. What am I missing?
Apr 3, 2008 at 6:38 PM
wow! That stinks. Let me check it out.
Apr 3, 2008 at 8:40 PM
Hold on now, when you call zip.Save("c:\zipme\") , you are passing in a directory name, yes?

That is incorrect usage. I guess the Save(string) method should check. But you must specify a filename, not a directory name, when calling that Save() method. Try that ?

Or maybe you are specifying a real filename. I don't know for sure. When I tried this, it worked for me.

If you think you are using it correctly, can you send me a short test case? It should be about 30 lines of code. I just added some unit tests to the DotNetZip solution (not yet released here), and in the test that covers an empty root directory, it just works.

        public void ZipDirectoryWithEmptyRoot()
            int i, j;
            int entries = 0;
            string currentDir = System.IO.Directory.GetCurrentDirectory();
            string TopLevelDir = GenerateUniqueFilename("tmp");
            int subdirCount = _rnd.Next(2) + 2;
            for (i = 0; i < subdirCount; i++)
                string Subdir = GenerateUniqueFilename("tmp", TopLevelDir);
                int fileCount = _rnd.Next(2) + 2;
                for (j = 0; j < fileCount; j++)
                    CreateUniqueFile("bin", Subdir, _rnd.Next(10000) + 5000);
            string ZipFileToCreate = GenerateUniqueFilename("zip");
            Assert.IsFalse(System.IO.File.Exists(ZipFileToCreate), "The temporary zip file '{0}' already exists.", ZipFileToCreate);
            string RelativeDir = System.IO.Path.GetFileName(TopLevelDir);
            using (ZipFile zip = new ZipFile(ZipFileToCreate))
            Assert.IsTrue(CheckZip(ZipFileToCreate, entries),
                    "Zip file created seems to be invalid.");
Apr 19, 2008 at 8:21 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.