-
-
Save Su-s/438be493ae692318c73e30367cbc5c2a to your computer and use it in GitHub Desktop.
| using System; | |
| using System.IO; | |
| using System.IO.Compression; | |
| using System.Text; | |
| namespace TarExample | |
| { | |
| public class Tar | |
| { | |
| /// <summary> | |
| /// Extracts a <i>.tar.gz</i> archive to the specified directory. | |
| /// </summary> | |
| /// <param name="filename">The <i>.tar.gz</i> to decompress and extract.</param> | |
| /// <param name="outputDir">Output directory to write the files.</param> | |
| public static void ExtractTarGz(string filename, string outputDir) | |
| { | |
| using (var stream = File.OpenRead(filename)) | |
| ExtractTarGz(stream, outputDir); | |
| } | |
| /// <summary> | |
| /// Extracts a <i>.tar.gz</i> archive stream to the specified directory. | |
| /// </summary> | |
| /// <param name="stream">The <i>.tar.gz</i> to decompress and extract.</param> | |
| /// <param name="outputDir">Output directory to write the files.</param> | |
| public static void ExtractTarGz(Stream stream, string outputDir) | |
| { | |
| using (var gzip = new GZipStream(stream, CompressionMode.Decompress)) | |
| { | |
| // removed convertation to MemoryStream | |
| ExtractTar(gzip, outputDir); | |
| } | |
| } | |
| /// <summary> | |
| /// Extractes a <c>tar</c> archive to the specified directory. | |
| /// </summary> | |
| /// <param name="filename">The <i>.tar</i> to extract.</param> | |
| /// <param name="outputDir">Output directory to write the files.</param> | |
| public static void ExtractTar(string filename, string outputDir) | |
| { | |
| using (var stream = File.OpenRead(filename)) | |
| ExtractTar(stream, outputDir); | |
| } | |
| /// <summary> | |
| /// Extractes a <c>tar</c> archive to the specified directory. | |
| /// </summary> | |
| /// <param name="stream">The <i>.tar</i> to extract.</param> | |
| /// <param name="outputDir">Output directory to write the files.</param> | |
| public static void ExtractTar(Stream stream, string outputDir) | |
| { | |
| var buffer = new byte[100]; | |
| // store current position here | |
| long pos = 0; | |
| while (true) | |
| { | |
| pos += stream.Read(buffer, 0, 100); | |
| var name = Encoding.ASCII.GetString(buffer).Trim('\0'); | |
| if (String.IsNullOrWhiteSpace(name)) | |
| break; | |
| FakeSeekForward(stream, 24); | |
| pos += 24; | |
| pos += stream.Read(buffer, 0, 12); | |
| var size = Convert.ToInt64(Encoding.UTF8.GetString(buffer, 0, 12).Trim('\0').Trim(), 8); | |
| FakeSeekForward(stream, 376); | |
| pos += 376; | |
| var output = Path.Combine(outputDir, name); | |
| if (!Directory.Exists(Path.GetDirectoryName(output))) | |
| Directory.CreateDirectory(Path.GetDirectoryName(output)); | |
| if (!name.Equals("./", StringComparison.InvariantCulture)) | |
| { | |
| using (var str = File.Open(output, FileMode.OpenOrCreate, FileAccess.Write)) | |
| { | |
| var buf = new byte[size]; | |
| pos += stream.Read(buf, 0, buf.Length); | |
| str.Write(buf, 0, buf.Length); | |
| } | |
| } | |
| var offset = (int)(512 - (pos % 512)); | |
| if (offset == 512) | |
| offset = 0; | |
| FakeSeekForward(stream, offset); | |
| pos += offset; | |
| } | |
| } | |
| private static void FakeSeekForward(Stream stream, int offset) | |
| { | |
| if (stream.CanSeek) | |
| stream.Seek(offset, SeekOrigin.Current); | |
| else | |
| { | |
| int bytesRead = 0; | |
| var buffer = new byte[offset]; | |
| while (bytesRead < offset) | |
| { | |
| int read = stream.Read(buffer, bytesRead, offset - bytesRead); | |
| if (read == 0) | |
| throw new EndOfStreamException(); | |
| bytesRead += read; | |
| } | |
| } | |
| } | |
| } | |
| } |
Thx for the update.
But it still did not help me, because it doesnt support single files bigger than 2GB.
the line
var buf = new byte[size];
throws an OverflowException when called with bigger values.
single byte array max size is that
https://stackoverflow.com/questions/3944320/maximum-length-of-byte/53967254
hello.. i am trying to decompress at tar.gz file. in it there there is one gz file which comtains one tar file and that tar file contains multiple tsv files. when i try to run your code.. i get error on line 58 saying The archive entry was compressed using an unsupported compression method. .. any advise?
@naveenvermaemail85 probably cannot do anything, this one supports "GZipStream",
other formats are BZip2 or LZMA...and maybe more (so try to look for c# libs to decompress those methods) or SharpCompress can report method also.
Modified the tgz decompression to support the tgz files of actual size more than 2GB