diff --git a/src/SharpCompress/Archives/Tar/TarArchive.cs b/src/SharpCompress/Archives/Tar/TarArchive.cs index 35d7fd15..961c1f6e 100644 --- a/src/SharpCompress/Archives/Tar/TarArchive.cs +++ b/src/SharpCompress/Archives/Tar/TarArchive.cs @@ -182,7 +182,7 @@ namespace SharpCompress.Archives.Tar IEnumerable oldEntries, IEnumerable newEntries) { - using (var writer = new TarWriter(stream, options)) + using (var writer = new TarWriter(stream, new TarWriterOptions(options))) { foreach (var entry in oldEntries.Concat(newEntries) .Where(x => !x.IsDirectory)) diff --git a/src/SharpCompress/Writers/Tar/TarWriter.cs b/src/SharpCompress/Writers/Tar/TarWriter.cs index db7bc97a..659c60e1 100644 --- a/src/SharpCompress/Writers/Tar/TarWriter.cs +++ b/src/SharpCompress/Writers/Tar/TarWriter.cs @@ -11,9 +11,13 @@ namespace SharpCompress.Writers.Tar { public class TarWriter : AbstractWriter { - public TarWriter(Stream destination, WriterOptions options) + private bool finalizeArchiveOnClose; + + public TarWriter(Stream destination, TarWriterOptions options) : base(ArchiveType.Tar, options) { + finalizeArchiveOnClose = options.FinalizeArchiveOnClose; + if (!destination.CanWrite) { throw new ArgumentException("Tars require writable streams."); @@ -97,8 +101,10 @@ namespace SharpCompress.Writers.Tar { if (isDisposing) { - PadTo512(0, true); - PadTo512(0, true); + if (finalizeArchiveOnClose) { + PadTo512(0, true); + PadTo512(0, true); + } switch (OutputStream) { case BZip2Stream b: diff --git a/src/SharpCompress/Writers/Tar/TarWriterOptions.cs b/src/SharpCompress/Writers/Tar/TarWriterOptions.cs new file mode 100755 index 00000000..9174b23f --- /dev/null +++ b/src/SharpCompress/Writers/Tar/TarWriterOptions.cs @@ -0,0 +1,23 @@ +using SharpCompress.Archives; +using SharpCompress.Common; + +namespace SharpCompress.Writers.Tar +{ + public class TarWriterOptions : WriterOptions + { + /// + /// Indicates if archive should be finalized (by 2 empty blocks) on close. + /// + public bool FinalizeArchiveOnClose { get; } + + public TarWriterOptions(CompressionType compressionType, bool finalizeArchiveOnClose) + : base(compressionType) + { + FinalizeArchiveOnClose = finalizeArchiveOnClose; + } + + internal TarWriterOptions(WriterOptions options) : this(options.CompressionType, true) + { + } + } +} \ No newline at end of file diff --git a/src/SharpCompress/Writers/WriterFactory.cs b/src/SharpCompress/Writers/WriterFactory.cs index b623ee63..1f1c01a5 100644 --- a/src/SharpCompress/Writers/WriterFactory.cs +++ b/src/SharpCompress/Writers/WriterFactory.cs @@ -27,7 +27,7 @@ namespace SharpCompress.Writers } case ArchiveType.Tar: { - return new TarWriter(stream, writerOptions); + return new TarWriter(stream, new TarWriterOptions(writerOptions)); } default: { diff --git a/tests/SharpCompress.Test/Tar/TarWriterTests.cs b/tests/SharpCompress.Test/Tar/TarWriterTests.cs index faeabd22..4b0b2168 100644 --- a/tests/SharpCompress.Test/Tar/TarWriterTests.cs +++ b/tests/SharpCompress.Test/Tar/TarWriterTests.cs @@ -1,4 +1,6 @@ -using SharpCompress.Common; +using System.IO; +using SharpCompress.Common; +using SharpCompress.Writers.Tar; using Xunit; namespace SharpCompress.Test.Tar @@ -34,5 +36,22 @@ namespace SharpCompress.Test.Tar { Assert.Throws(() => Write(CompressionType.Rar, "Zip.ppmd.noEmptyDirs.zip", "Zip.ppmd.noEmptyDirs.zip")); } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void Tar_Finalize_Archive(bool finalizeArchive) + { + using (MemoryStream stream = new MemoryStream()) + using (Stream content = File.OpenRead(Path.Combine(ORIGINAL_FILES_PATH, "jpg", "test.jpg"))) { + using (TarWriter writer = new TarWriter(stream, new TarWriterOptions(CompressionType.None, finalizeArchive))) { + writer.Write("doesn't matter", content, null); + } + + var paddedContentWithHeader = content.Length / 512 * 512 + 512 + 512; + var expectedStreamLength = finalizeArchive ? paddedContentWithHeader + 512 * 2 : paddedContentWithHeader; + Assert.Equal(expectedStreamLength, stream.Length); + } + } } }