From 6a06ca303344b33ed421bf73f240a541e582c7ca Mon Sep 17 00:00:00 2001 From: Richard Webb Date: Wed, 22 Apr 2020 22:24:43 +0100 Subject: [PATCH 1/2] Add a variant of FastZip.CreateZip with a leaveOpen parameter to control output stream disposal --- src/ICSharpCode.SharpZipLib/Zip/FastZip.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/ICSharpCode.SharpZipLib/Zip/FastZip.cs b/src/ICSharpCode.SharpZipLib/Zip/FastZip.cs index 2e1719e88..e210eaeca 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/FastZip.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/FastZip.cs @@ -361,6 +361,20 @@ public void CreateZip(string zipFileName, string sourceDirectory, bool recurse, /// The directory filter to apply. /// The is closed after creation. public void CreateZip(Stream outputStream, string sourceDirectory, bool recurse, string fileFilter, string directoryFilter) + { + CreateZip(outputStream, sourceDirectory, recurse, fileFilter, directoryFilter, false); + } + + /// + /// Create a zip archive sending output to the passed. + /// + /// The stream to write archive data to. + /// The directory to source files from. + /// True to recurse directories, false for no recursion. + /// The file filter to apply. + /// The directory filter to apply. + /// true to leave open after the zip has been created, false to dispose it. + public void CreateZip(Stream outputStream, string sourceDirectory, bool recurse, string fileFilter, string directoryFilter, bool leaveOpen) { NameTransform = new ZipNameTransform(sourceDirectory); sourceDirectory_ = sourceDirectory; @@ -368,6 +382,7 @@ public void CreateZip(Stream outputStream, string sourceDirectory, bool recurse, using (outputStream_ = new ZipOutputStream(outputStream)) { outputStream_.SetLevel((int)CompressionLevel); + outputStream_.IsStreamOwner = !leaveOpen; if (password_ != null) { From 54f787f8e4e2f010290aa047f2c143976f291be3 Mon Sep 17 00:00:00 2001 From: Richard Webb Date: Mon, 22 Jun 2020 23:56:00 +0100 Subject: [PATCH 2/2] unit test for FastZip.CreateZip leaving the stream open or disposed as required --- .../Zip/FastZipHandling.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs index 67b481f65..259bde43b 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs @@ -625,5 +625,45 @@ public void SetDirectoryModifiedDate() Directory.Delete(targetDir, true); } } + + /// + /// Test for https://github.com/icsharpcode/SharpZipLib/issues/78 + /// + /// if true, the stream given to CreateZip should be left open, if false it should be disposed. + [TestCase(true)] + [TestCase(false)] + [Category("Zip")] + [Category("CreatesTempFile")] + public void CreateZipShouldLeaveOutputStreamOpenIfRequested(bool leaveOpen) + { + const string tempFileName = "a(2).dat"; + + using (var tempFolder = new Utils.TempDir()) + { + // Create test input file + string addFile = Path.Combine(tempFolder.Fullpath, tempFileName); + MakeTempFile(addFile, 16); + + // Create the zip with fast zip + var target = new TrackedMemoryStream(); + var fastZip = new FastZip(); + + fastZip.CreateZip(target, tempFolder.Fullpath, false, @"a\(2\)\.dat", null, leaveOpen: leaveOpen); + + // Check that the output stream was disposed (or not) as expected + Assert.That(target.IsDisposed, Is.Not.EqualTo(leaveOpen), "IsDisposed should be the opposite of leaveOpen"); + + // Check that the file contents are correct in both cases + var archive = new MemoryStream(target.ToArray()); + using (ZipFile zf = new ZipFile(archive)) + { + Assert.AreEqual(1, zf.Count); + ZipEntry entry = zf[0]; + Assert.AreEqual(tempFileName, entry.Name); + Assert.AreEqual(16, entry.Size); + Assert.IsTrue(zf.TestArchive(true)); + } + } + } } }