Decompress tar.lz tar.bz2 cause exception #741

Open
opened 2026-01-29 22:16:44 +00:00 by claunia · 13 comments
Owner

Originally created by @zhuxb711 on GitHub (Dec 9, 2025).

Originally assigned to: @Copilot on GitHub.

I tried to decompress the tar.bz2 or tar.lz that created from the SharpCompress

But unfortunately, I got the exception:
Cannot determine compressed stream type. Supported Archive Formats: Zip, Rar, 7Zip, GZip, Tar

StackTrace:
    at SharpCompress.Archives.ArchiveFactory.FindFactory[T](Stream stream) in /_/src/SharpCompress/Archives/ArchiveFactory.cs:line 164
    at SharpCompress.Archives.ArchiveFactory.Open(Stream stream, ReaderOptions readerOptions) in /_/src/SharpCompress/Archives/ArchiveFactory.cs:line 24
Originally created by @zhuxb711 on GitHub (Dec 9, 2025). Originally assigned to: @Copilot on GitHub. I tried to decompress the `tar.bz2` or `tar.lz` that created from the SharpCompress But unfortunately, I got the exception: `Cannot determine compressed stream type. Supported Archive Formats: Zip, Rar, 7Zip, GZip, Tar` ``` StackTrace: at SharpCompress.Archives.ArchiveFactory.FindFactory[T](Stream stream) in /_/src/SharpCompress/Archives/ArchiveFactory.cs:line 164 at SharpCompress.Archives.ArchiveFactory.Open(Stream stream, ReaderOptions readerOptions) in /_/src/SharpCompress/Archives/ArchiveFactory.cs:line 24 ```
claunia added the bugquestion labels 2026-01-29 22:16:44 +00:00
Author
Owner

@zhuxb711 commented on GitHub (Dec 9, 2025):

tar & tar.gz works fine

@zhuxb711 commented on GitHub (Dec 9, 2025): tar & tar.gz works fine
Author
Owner

@adamhathcock commented on GitHub (Dec 9, 2025):

How are you access those formats? FileStreams or another stream?

@adamhathcock commented on GitHub (Dec 9, 2025): How are you access those formats? FileStreams or another stream?
Author
Owner

@zhuxb711 commented on GitHub (Dec 10, 2025):

Use FileStream directly @adamhathcock

@zhuxb711 commented on GitHub (Dec 10, 2025): Use FileStream directly @adamhathcock
Author
Owner

@adamhathcock commented on GitHub (Dec 10, 2025):

I think the problem is that bzip2 and lzip only work for forward only streams and there is no archive implementation for either.

GZip works mainly because it's got a single entry.

What is the rest of the code do you have? Try ReaderFactory instead?

@adamhathcock commented on GitHub (Dec 10, 2025): I think the problem is that bzip2 and lzip only work for forward only streams and there is no archive implementation for either. GZip works mainly because it's got a single entry. What is the rest of the code do you have? Try ReaderFactory instead?
Author
Owner

@zhuxb711 commented on GitHub (Dec 15, 2025):

Image

But Archive API & Reader API should be both supported as your FORMAT.md indicated

@zhuxb711 commented on GitHub (Dec 15, 2025): <img width="1031" height="343" alt="Image" src="https://github.com/user-attachments/assets/eec08d8a-d5a5-4333-b9d8-8eacc9f5a906" /> But Archive API & Reader API should be both supported as your FORMAT.md indicated
Author
Owner

@zhuxb711 commented on GitHub (Dec 15, 2025):

Actually, I use the ReaderFactory to extract the files, but before that I would use the ArchiveFactory to open the file and extract the TotalUncompressSize. I think even "forward only streams" should be able to calculate the TotalUncompressSize. Any suggestion? An alternative way is to walk the Reader first to get TotalUncompressSize and walk the Reader again to extract the files. Will it cost to much?

using (IArchive Archive = ArchiveFactory.Open(SourceStream, Options))
{
    ulong TotalSize = Convert.ToUInt64(Archive.TotalUncompressSize);
}
@zhuxb711 commented on GitHub (Dec 15, 2025): Actually, I use the ReaderFactory to extract the files, but before that I would use the ArchiveFactory to open the file and extract the `TotalUncompressSize`. I think even "forward only streams" should be able to calculate the `TotalUncompressSize`. Any suggestion? An alternative way is to walk the Reader first to get `TotalUncompressSize` and walk the Reader again to extract the files. Will it cost to much? ```csharp using (IArchive Archive = ArchiveFactory.Open(SourceStream, Options)) { ulong TotalSize = Convert.ToUInt64(Archive.TotalUncompressSize); } ```
Author
Owner

@zhuxb711 commented on GitHub (Dec 15, 2025):

Also I need the ArchiveFactory to open the stream first to determine whether the archive is solid or 7zip. Which could not be opened from ReaderFactory. This is how my code works:

using (IArchive Archive = ArchiveFactory.Open(SourceStream, Options))
{
    ulong TotalSize = Convert.ToUInt64(Archive.TotalUncompressSize);

    if (SourceStream.CanSeek && SourceStream.Position > 0)
    {
        SourceStream.Seek(0, SeekOrigin.Begin);
    }

    if (Archive.IsSolid || Archive.Type == ArchiveType.SevenZip)
    {
        using (IReader ArchiveReader = Archive.ExtractAllEntries())
        {
            await ExtractCoreAsync(ArchiveReader, ExtractFolder, TotalSize, ProgressHandler, CancelToken); // TotalUncompressSize would be used in ExtractCoreAsync for progress calculation
        }
    }
    else
    {
        using (IReader ArchiveReader = ReaderFactory.Open(SourceStream, Options))
        {
            await ExtractCoreAsync(ArchiveReader, ExtractFolder, TotalSize, ProgressHandler, CancelToken); // TotalUncompressSize would be used in ExtractCoreAsync for progress calculation
        }
    }
}
@zhuxb711 commented on GitHub (Dec 15, 2025): Also I need the ArchiveFactory to open the stream first to determine whether the archive is solid or 7zip. Which could not be opened from ReaderFactory. This is how my code works: ```csharp using (IArchive Archive = ArchiveFactory.Open(SourceStream, Options)) { ulong TotalSize = Convert.ToUInt64(Archive.TotalUncompressSize); if (SourceStream.CanSeek && SourceStream.Position > 0) { SourceStream.Seek(0, SeekOrigin.Begin); } if (Archive.IsSolid || Archive.Type == ArchiveType.SevenZip) { using (IReader ArchiveReader = Archive.ExtractAllEntries()) { await ExtractCoreAsync(ArchiveReader, ExtractFolder, TotalSize, ProgressHandler, CancelToken); // TotalUncompressSize would be used in ExtractCoreAsync for progress calculation } } else { using (IReader ArchiveReader = ReaderFactory.Open(SourceStream, Options)) { await ExtractCoreAsync(ArchiveReader, ExtractFolder, TotalSize, ProgressHandler, CancelToken); // TotalUncompressSize would be used in ExtractCoreAsync for progress calculation } } } ```
Author
Owner

@zhuxb711 commented on GitHub (Jan 7, 2026):

@adamhathcock Any suggestion?

@zhuxb711 commented on GitHub (Jan 7, 2026): @adamhathcock Any suggestion?
Author
Owner

@adamhathcock commented on GitHub (Jan 7, 2026):

You have several issues noted that are separate:

Actually, I use the ReaderFactory to extract the files, but before that I would use the ArchiveFactory to open the file and extract the TotalUncompressSize. I think even "forward only streams" should be able to calculate the TotalUncompressSize. Any suggestion? An alternative way is to walk the Reader first to get TotalUncompressSize and walk the Reader again to extract the files. Will it cost to much?

using (IArchive Archive = ArchiveFactory.Open(SourceStream, Options))
{
ulong TotalSize = Convert.ToUInt64(Archive.TotalUncompressSize);
}

ReaderFactory is forward-only and can't get the total size without walking the stream. ArchiveFactory (seekable streams) for zip uses the dictionary. Different formats work differently so I can't answer this.

Also I need the ArchiveFactory to open the stream first to determine whether the archive is solid or 7zip. Which could not be opened from ReaderFactory. This is how my code works:

using (IArchive Archive = ArchiveFactory.Open(SourceStream, Options))
{
ulong TotalSize = Convert.ToUInt64(Archive.TotalUncompressSize);

if (SourceStream.CanSeek && SourceStream.Position > 0)
{
    SourceStream.Seek(0, SeekOrigin.Begin);
}

if (Archive.IsSolid || Archive.Type == ArchiveType.SevenZip)
{
    using (IReader ArchiveReader = Archive.ExtractAllEntries())
    {
        await ExtractCoreAsync(ArchiveReader, ExtractFolder, TotalSize, ProgressHandler, CancelToken); // TotalUncompressSize would be used in ExtractCoreAsync for progress calculation
    }
}
else
{
    using (IReader ArchiveReader = ReaderFactory.Open(SourceStream, Options))
    {
        await ExtractCoreAsync(ArchiveReader, ExtractFolder, TotalSize, ProgressHandler, CancelToken); // TotalUncompressSize would be used in ExtractCoreAsync for progress calculation
    }
}

}

This was attempted to be addressed here: https://github.com/adamhathcock/sharpcompress/issues/1070

@adamhathcock commented on GitHub (Jan 7, 2026): You have several issues noted that are separate: > Actually, I use the ReaderFactory to extract the files, but before that I would use the ArchiveFactory to open the file and extract the `TotalUncompressSize`. I think even "forward only streams" should be able to calculate the `TotalUncompressSize`. Any suggestion? An alternative way is to walk the Reader first to get `TotalUncompressSize` and walk the Reader again to extract the files. Will it cost to much? > > using (IArchive Archive = ArchiveFactory.Open(SourceStream, Options)) > { > ulong TotalSize = Convert.ToUInt64(Archive.TotalUncompressSize); > } ReaderFactory is forward-only and can't get the total size without walking the stream. ArchiveFactory (seekable streams) for zip uses the dictionary. Different formats work differently so I can't answer this. > Also I need the ArchiveFactory to open the stream first to determine whether the archive is solid or 7zip. Which could not be opened from ReaderFactory. This is how my code works: > > using (IArchive Archive = ArchiveFactory.Open(SourceStream, Options)) > { > ulong TotalSize = Convert.ToUInt64(Archive.TotalUncompressSize); > > if (SourceStream.CanSeek && SourceStream.Position > 0) > { > SourceStream.Seek(0, SeekOrigin.Begin); > } > > if (Archive.IsSolid || Archive.Type == ArchiveType.SevenZip) > { > using (IReader ArchiveReader = Archive.ExtractAllEntries()) > { > await ExtractCoreAsync(ArchiveReader, ExtractFolder, TotalSize, ProgressHandler, CancelToken); // TotalUncompressSize would be used in ExtractCoreAsync for progress calculation > } > } > else > { > using (IReader ArchiveReader = ReaderFactory.Open(SourceStream, Options)) > { > await ExtractCoreAsync(ArchiveReader, ExtractFolder, TotalSize, ProgressHandler, CancelToken); // TotalUncompressSize would be used in ExtractCoreAsync for progress calculation > } > } > } This was attempted to be addressed here: https://github.com/adamhathcock/sharpcompress/issues/1070
Author
Owner

@zhuxb711 commented on GitHub (Jan 7, 2026):

Seems PR 1077 did not provide a way to get IReader without checking

Archive.IsSolid || Archive.Type == ArchiveType.SevenZip

@zhuxb711 commented on GitHub (Jan 7, 2026): Seems [PR 1077](https://github.com/adamhathcock/sharpcompress/pull/1077) did not provide a way to get IReader without checking > Archive.IsSolid || Archive.Type == ArchiveType.SevenZip
Author
Owner

@adamhathcock commented on GitHub (Jan 7, 2026):

The issue says you can do the following without that check:

using var archive = ArchiveFactory.Open(testArchive);
        archive.WriteToDirectory(SCRATCH_FILES_PATH, options);
@adamhathcock commented on GitHub (Jan 7, 2026): The issue says you can do the following without that check: ``` using var archive = ArchiveFactory.Open(testArchive); archive.WriteToDirectory(SCRATCH_FILES_PATH, options); ```
Author
Owner

@zhuxb711 commented on GitHub (Jan 8, 2026):

The issue says you can do the following without that check:

using var archive = ArchiveFactory.Open(testArchive);
        archive.WriteToDirectory(SCRATCH_FILES_PATH, options);

In my use case, I have to control the extraction process by myself, therefore I would not use the WriteToDirectory because as a developer I would not assume the place that user extracting is local file system

@zhuxb711 commented on GitHub (Jan 8, 2026): > The issue says you can do the following without that check: > > ``` > using var archive = ArchiveFactory.Open(testArchive); > archive.WriteToDirectory(SCRATCH_FILES_PATH, options); > ``` In my use case, I have to control the extraction process by myself, therefore I would not use the `WriteToDirectory` because as a developer I would not assume the place that user extracting is local file system
Author
Owner

@adamhathcock commented on GitHub (Jan 8, 2026):

Please try the latest. I don't know what file you're trying and I think it's some error handling problem that is misleading you

@adamhathcock commented on GitHub (Jan 8, 2026): Please try the latest. I don't know what file you're trying and I think it's some error handling problem that is misleading you
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/sharpcompress#741