How to add an entry to an existing TAR-File using SharpZipLib

83 Views Asked by At

We are using SharpZipLib to create new TAR files with C# and this workes perfectly. Now we came to the situation where we had to add one more file to an existing TAR file. The size of the file increases but the new entry is not added in the catalog of the TAR file so that it cannot be extracted.

Additionally 7Zip shows the warning that there are data behind the payload data. So it seems that the catalog of the tar file is not correctly written.

We are using following TarFileWriter class:

namespace MyNamespace
{
    using System;
    using System.IO;
    using ICSharpCode.SharpZipLib.Tar;

    /// <summary>
    /// Writes data into a TAR-File.
    /// </summary>
    public class TarFileWriter : IFileWriter
    {
        public TarFileWriter(string filename, FileMode mode)
        {
            this.FileStream = File.Open(filename, mode);
            this.OutputStream = new TarOutputStream(this.FileStream, null);
        }

        private Stream FileStream { get; }

        private TarOutputStream OutputStream { get; }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool dispose)
        {
            if (dispose)
            {
                this.OutputStream.Dispose();
                this.FileStream.Dispose();
            }
        }

        public void WriteAllBytes(string filename, byte[] bytes)
        {
            var tarHeader = new TarHeader
            {
                Name = filename,
                ModTime = DateTime.Now,
            };
            var entry = new TarEntry(tarHeader)
            {
                Size = bytes.Length,
            };

            this.OutputStream.PutNextEntry(entry);
            this.OutputStream.Write(bytes, 0, bytes.Length);
            this.OutputStream.CloseEntry();
        }
    }
}

Using these tests, we get following results:

    [TestClass]
    public class FileToolTest
    {
        [TestMethod]
        public void CreateTarFile()
        {
            using (var tarFileWriter = new TarFileWriter(@"H:\TestTar.tar", FileMode.CreateNew))
            {
                tarFileWriter.WriteAllBytes("Test.data", new byte[] { 12, 34, 56 });
            }
        }

        [TestMethod]
        public void AddTarFile1()
        {
            using (var tarFileWriter = new TarFileWriter(@"H:\TestTar.tar", FileMode.Open))
            {
                tarFileWriter.WriteAllBytes("Test1.data", new byte[] { 12, 34, 56 });
            }
        }

        [TestMethod]
        public void AddTarFile2()
        {
            using (var tarFileWriter = new TarFileWriter(@"H:\TestTar.tar", FileMode.Append))
            {
                tarFileWriter.WriteAllBytes("Test2.data", new byte[] { 12, 34, 56 });
            }
        }
    }
  • The test CreateTarFile creates a correct tar file.
  • The test AddTarFile1 does not add a new entry to the tar file. It creates a new tar file and overwrites the existing one.
  • Finally the test AddTarFile2 indeed adds data to the tar file but as data behind the payload data and does not add the filename "Test2.data" to the entries of the tar file so that this entry cannot be extracted although it is somehow in the tar.

So: What is the correct way to add entries to an existing tar file?

0

There are 0 best solutions below