sharpcompress icon indicating copy to clipboard operation
sharpcompress copied to clipboard

System.NotSupportedException on reader.MoveToNextEntry()

Open Stuart88 opened this issue 3 years ago • 4 comments

Unzipping a 7z file fails with System.NotSupportedException on the last MoveToNextEntry() call.

On inspecting the results in file explorer, I can see it's successfully finished extraction, so I guess MoveToNextEntry() is hitting an error of some kind instead of discovering that it's at the end of the archive?.

If it helps, the 7z archive I'm working with can be downloaded here: https://www.nexusmods.com/oblivion/mods/5296?tab=files&file_id=1000024710

Stack Trace:

   at SharpCompress.Compressors.LZMA.DecoderRegistry.CreateDecoderStream(CMethodId id, Stream[] inStreams, Byte[] info, IPasswordProvider pass, Int64 limit)
   at SharpCompress.Compressors.LZMA.DecoderStreamHelper.CreateDecoderStream(Stream inStream, Int64 startPos, Int64[] packSizes, CFolder folderInfo, IPasswordProvider pass)
   at SharpCompress.Common.SevenZip.ArchiveDatabase.GetFolderStream(Stream stream, CFolder folder, IPasswordProvider pw)
   at SharpCompress.Archives.SevenZip.SevenZipArchive.SevenZipReader.<GetEntries>d__7.MoveNext()
   at SharpCompress.Readers.AbstractReader`2.MoveToNextEntry()
   at U_Mod.Models.ZipFileWorker.UncompressZip(String inFile, String outDirectory) in C:\Users\saitk\Programming\WPF\U-Mod\U-Mod\Models\ZipFileWorker.cs:line 181

Thanks :)

Stuart88 avatar Jun 27 '21 19:06 Stuart88

If you're extracting using the ReaderFactory, it seems that 7z support is missing there. As an workaround, you can try open it manually with SevenZipArchive.Open(). ~~But the progress seems not to work using this way~~ and self-writing a wrapper doesn't work because the RewindableStream class is mostly declared as internal.

You can use the event when calling ExtractAllEntries() on the archive like this:

using (var archive = SevenZipArchive.Open(archivePath)) {
    using (var reader = archive.ExtractAllEntries()) {
        reader.EntryExtractionProgress += Reader_EntryExtractionProgress;
        reader.WriteAllToDirectory(targetDir, options);
    }
}
private void Reader_EntryExtractionProgress(object sender, ReaderExtractionEventArgs<IEntry> e) {
    log.Info($"{e.Item.Key}: {e.ReaderProgress.PercentageRead} % read, {e.ReaderProgress.PercentageReadExact} % extracted");
}

Extracting other formats with the auto-detection of the ReaderFactory class can still be used. Until this is fixed, you just need to check yourself first if the archive is a 7z archive and extract it manually, otherwise use ReaderFactory like this:

if (SevenZipArchive.IsSevenZipFile(archivePath)) {
    ExtractSevenZip(archivePath, targetDir, options);
} else {
    ExtractWithAutoDetectFactory(archivePath, targetDir, options);
}

It's a bit more manual work, but it works and both allow to show the correct progress (usefull on larger files and/or slower machines/disks).

DMW007 avatar Jan 07 '22 22:01 DMW007

Thanks for helping @DMW007

Readers aren't used with 7Zip because 7Zip requires random access on the stream. Reader is built for non-seekable streams while Archive is built for seekable streams.

adamhathcock avatar Jan 09 '22 09:01 adamhathcock

Thank you @adamhathcock for the explanation. I'd suggest to document this in the usage guide, so it's clear that the auto extractor cannot work with 7zip archives.

DMW007 avatar Jan 09 '22 16:01 DMW007

ArchiveFactory does work with 7Zip though

adamhathcock avatar Jan 10 '22 08:01 adamhathcock