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.
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.
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);
}
}
The following solution might work as well: How to Create a Tar GZipped File in C#
I haven't tested it, as I am not going to work with tar.gz files after all, but looks thorough and people said it works.
© 2022 - 2024 — McMap. All rights reserved.