diff --git a/src/SharpCompress/Archives/Zip/ZipArchive.cs b/src/SharpCompress/Archives/Zip/ZipArchive.cs index f0889668c..3a75d10ad 100644 --- a/src/SharpCompress/Archives/Zip/ZipArchive.cs +++ b/src/SharpCompress/Archives/Zip/ZipArchive.cs @@ -182,12 +182,18 @@ protected override void SaveTo(Stream stream, WriterOptions options, { using (var writer = new ZipWriter(stream, new ZipWriterOptions(options))) { - foreach (var entry in oldEntries.Concat(newEntries) - .Where(x => !x.IsDirectory)) + foreach (var entry in oldEntries.Concat(newEntries)) { - using (var entryStream = entry.OpenEntryStream()) + if (entry.IsDirectory) { + //TODO What do to here? + } + else + { + using (var entryStream = entry.OpenEntryStream()) + { writer.Write(entry.Key, entryStream, entry.LastModifiedTime); + } } } } @@ -210,5 +216,11 @@ protected override IReader CreateReaderForSolidExtraction() stream.Position = 0; return ZipReader.Open(stream, ReaderOptions); } + + public void AddDirectory(string combine) + { + combine += "/"; + var entry = AddEntry(combine, new MemoryStream()); + } } } \ No newline at end of file diff --git a/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs b/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs index 4b4bbf362..57cd6ae0d 100644 --- a/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs +++ b/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs @@ -41,7 +41,19 @@ internal ZipWritableArchiveEntry(ZipArchive archive, Stream stream, string path, public override bool IsEncrypted => false; - public override bool IsDirectory => false; + public override bool IsDirectory + { + get + { + if (Key.EndsWith("/")) + { + return true; + } + + //.NET Framework 4.5 : System.IO.Compression::CreateFromDirectory() probably writes backslashes to headers + return CompressedSize == 0 && Key.EndsWith("\\"); + } + } public override bool IsSplit => false; diff --git a/tests/SharpCompress.Test/Zip/AddFolderTest.cs b/tests/SharpCompress.Test/Zip/AddFolderTest.cs new file mode 100644 index 000000000..3c0837155 --- /dev/null +++ b/tests/SharpCompress.Test/Zip/AddFolderTest.cs @@ -0,0 +1,24 @@ +namespace SharpCompress.Test.Zip +{ + using System.IO; + + using SharpCompress.Archives; + using SharpCompress.Archives.Zip; + using SharpCompress.Common; + using SharpCompress.Writers.Zip; + + using Xunit; + + public class AddFolderTest + { + [Fact] + public void When_subject_should_expectation() + { + using (var zip = ZipArchive.Create()) + { + zip.AddDirectory(Path.Combine("Hallo", "Welt")); + zip.SaveTo(@"D:\Hallo.zip", new ZipWriterOptions(CompressionType.Deflate) { ArchiveComment = "HalloWelt" }); + } + } + } +} diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index 031698d84..4e1a3ccba 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -461,5 +461,23 @@ public void TestSharpCompressWithEmptyStream() } } } + + [Fact] + public void When_adding_empty_folder_should_only_contain_folders() + { + var stream = new MemoryStream(); + string folderName = "EmptyFolder"; + using (var zipArchive = ZipArchive.Create()) + { + zipArchive.AddDirectory(folderName); + zipArchive.SaveTo(stream); + } + + using (var zipArchive = ZipArchive.Open(stream)) + { + Assert.True(zipArchive.Entries.SingleOrDefault(me => me.Key.Contains("folderName")) != null); + Assert.True(zipArchive.Entries.All(me => me.IsDirectory)); + } + } } }