adamhathcock / sharpcompress

SharpCompress is a fully managed C# library to deal with many compression types and formats.
MIT License
2.26k stars 480 forks source link

How to extract from one level below the archive #813

Open Bluscream opened 6 months ago

Bluscream commented 6 months ago

I have the following code:

public static void Extract(string archivePath, string destPath, string archiveRoot = "/") {
    using (Stream stream = File.OpenRead(archivePath)) {
        var reader = ArchiveFactory.Open(stream);
        var entries = reader.Entries.ToList();
        if (entries.Count < 1) throw new ArchiveException($"Empty archive: {archivePath}");
        var firstEntry = entries.First();
        var isGithubTarball = (entries.Count == 1 && firstEntry.IsDirectory && firstEntry.Key.Contains("-"));
        Console.WriteLine($"Extracting {archivePath} to {destPath} (root: {archiveRoot}) [entries: {entries.Count}, isGithubTarball: {isGithubTarball}]");
        if (isGithubTarball && archiveRoot == "/") {
            Extract(archivePath, destPath, archiveRoot + firstEntry.Key); return;
        }
        foreach (var entry in reader.Entries) {
            if (!entry.IsDirectory && entry.Key != null) { // Add null check here
                string entryPath = entry.Key;
                if (entryPath.StartsWith(archiveRoot)) {
                    entryPath = entryPath.Substring(archiveRoot.Length);
                }
                entry.WriteToDirectory(Path.Combine(destPath, entryPath), new ExtractionOptions() {
                    ExtractFullPath = true,
                    Overwrite = true
                });
            }
        }
    }
}

and the first entry has a CRC but it's key or other attributes are always null:

Related archive: https://github.com/dayz-cc/serverfiles/archive/refs/heads/main.tar.gz Related phind convo: https://www.phind.com/agent?cache=cltk80vqr001ola08l98kgz9b

adamhathcock commented 6 months ago

use entry.OpenEntryStream and you can point that stream where ever you want...this is what WriteToDirectory uses

https://github.com/adamhathcock/sharpcompress/blob/master/src/SharpCompress/Archives/IArchiveEntryExtensions.cs