Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create tar.gz file in C#


I have tried SevenZipLib and SevenZipSharp, but without success. Can someone give me a working example of archiving a text file to tar.gz, using any free library?
I know it's not the best way to go for zipping, but it's a requirement I have.

like image 587
Stavros Avatar asked Aug 05 '15 15:08

Stavros


People also ask

How do I create a tar.gz file?

The procedure to create a tar.gz file on Linux is as follows: Open the terminal application in Linux. Run tar command to create an archived named file.tar.gz for given directory name by running: tar -czvf file.tar.gz directory. Verify tar.gz file using the ls command and tar command.

How do I create a tar file?

To create a tar file, use the cvf command line option, list the name of the resulting tar file first followed by a directory whose contents you want to tar-up. If you forget to list the tar file target (hw10. tar) in the tar command, tar will exit with an error message.

Can we gzip tar file?

Tar itself does not support compression directly. It is often used with a compression utility such as Gzip or Bzip2 to space disk space. These compression utilities generally only compress a single file, so they are used in combination with Tar, which can produce a single file from many files.

What is tar in C?

tar which is the Archive of all . c files in current directory. $ tar cvf file.tar *.c.


2 Answers

Perhaps the most popular package in NuGet that supports TAR is SharpZipLib. Its wiki includes examples for working with tar.gz files, including creation. The linked example archives an entire folder.

To archive a single file, the sample can be simplified to this:

private void CreateTarGZ(string tgzFilename, string fileName)
{
    using (var outStream = File.Create(tgzFilename))
    using (var gzoStream = new GZipOutputStream(outStream))
    using (var tarArchive = TarArchive.CreateOutputTarArchive(gzoStream))
    {
        tarArchive.RootPath = Path.GetDirectoryName(fileName);

        var tarEntry = TarEntry.CreateEntryFromFile(fileName);
        tarEntry.Name = Path.GetFileName(fileName);

        tarArchive.WriteEntry(tarEntry,true);
    }
}

Essentially, you need to create a TarEntry for each folder and file you want to store.

like image 101
Panagiotis Kanavos Avatar answered Sep 28 '22 05:09

Panagiotis Kanavos


Not a fan of the examples on how to compress a directory provided by SharpZipLib because instead of keeping the folder structure in the directory you are trying to convert to a .tgz, their method copies the folder path that leads to whatever directory you are trying to compress.

For example:

If you were trying to compress folderA (located in: //filer/folder1/folderA) with a single file called foo.c, then after converting folderA into a .tgz, the path to foo.c within the .tgz file would be:

folderA.tgz/filer/folder1/foo.c

This solution omits the extra files within the .tgz, resulting in:

folderA.tgz/foo.c

using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
using ICSharpCode.SharpZipLib.Zip;
using System.IO;

/// <summary>
/// Creates a .tgz file using everything in the sourceDirectory. The .tgz file will be titled {tgzFileName}.tgz and will be located in targetDirectory.
/// </summary>
/// <param name="sourceDirectory">Directory to compress into a .tgz</param>
/// <param name="tgzFileName">Name of .tgz file</param>
/// <param name="targetDirectory">Directory where {tgzFileName}.tgz should be located.</param>
/// <param name="deleteSourceDirectoryUponCompletion">Will delete sourceDirectory if <see langword="true"/></param>
/// <returns>Path to .tgz file</returns>
public string CreateTGZ(string sourceDirectory, string tgzFileName, string targetDirectory, bool deleteSourceDirectoryUponCompletion = false)
{
    if (!tgzFileName.EndsWith(".tgz"))
    {
        tgzFileName = tgzFileName + ".tgz";
    }
    using (var outStream = File.Create(Path.Combine(targetDirectory, tgzFileName)))
    using (var gzoStream = new GZipOutputStream(outStream))
    {
        var tarArchive = TarArchive.CreateOutputTarArchive(gzoStream);

        // Note that the RootPath is currently case sensitive and must be forward slashes e.g. "c:/temp"
        // and must not end with a slash, otherwise cuts off first char of filename
        tarArchive.RootPath = sourceDirectory.Replace('\\', '/');
        if (tarArchive.RootPath.EndsWith("/"))
        {
            tarArchive.RootPath = tarArchive.RootPath.Remove(tarArchive.RootPath.Length - 1);
        }

        AddDirectoryFilesToTGZ(tarArchive, sourceDirectory);

        if (deleteSourceDirectoryUponCompletion)
        {
            File.Delete(sourceDirectory);
        }

        var tgzPath = (tarArchive.RootPath + ".tgz").Replace('/', '\\');

        tarArchive.Close();
        return tgzPath;
    }
}

private void AddDirectoryFilesToTGZ(TarArchive tarArchive, string sourceDirectory)
{
    AddDirectoryFilesToTGZ(tarArchive, sourceDirectory, string.Empty);
}

private void AddDirectoryFilesToTGZ(TarArchive tarArchive, string sourceDirectory, string currentDirectory)
{
    var pathToCurrentDirectory = Path.Combine(sourceDirectory, currentDirectory);

    // Write each file to the tgz.
    var filePaths = Directory.GetFiles(pathToCurrentDirectory);
    foreach (string filePath in filePaths)
    {
        var tarEntry = TarEntry.CreateEntryFromFile(filePath);

        // Name sets where the file is written. Write it in the same spot it exists in the source directory
        tarEntry.Name = filePath.Replace(sourceDirectory, "");

        // If the Name starts with '\' then an extra folder (with a blank name) will be created, we don't want that.
        if (tarEntry.Name.StartsWith('\\'))
        {
            tarEntry.Name = tarEntry.Name.Substring(1);
        }
        tarArchive.WriteEntry(tarEntry, true);
    }

    // Write directories to tgz
    var directories = Directory.GetDirectories(pathToCurrentDirectory);
    foreach (string directory in directories)
    {
        AddDirectoryFilesToTGZ(tarArchive, sourceDirectory, directory);
    }
}
like image 44
Window Avatar answered Sep 28 '22 03:09

Window