Skip to content
This repository has been archived by the owner on Apr 9, 2024. It is now read-only.

I have an exception in SevenZipExtractor.BeginExtractArchive(string directory) when unpacking a stream #25

Open
altbodhi opened this issue Sep 26, 2018 · 7 comments

Comments

@altbodhi
Copy link

       var zipStream = new FileStream("c:\\backup\\file.zip", FileMode.Open);
            SevenZip.SevenZipBase.SetLibraryPath("x86\\7z.dll");
            var z = new SevenZip.SevenZipExtractor(zipStream, "pass");
                 z.BeginExtractArchive("c:\\tmp\\test_ext");

.net 4.5.2

The specified stream can not seek or read.
Имя параметра: stream

Server stack trace:
в SevenZip.SevenZipExtractor.ValidateStream(Stream stream) в C:\projects\SevenZipSharp\SevenZip\SevenZipExtractor.cs:строка 691
в SevenZip.SevenZipExtractor.Init(Stream stream) в C:\projects\SevenZipSharp\SevenZip\SevenZipExtractor.cs:строка 100
в SevenZip.SevenZipExtractor.RecreateInstanceIfNeeded() в C:\projects\SevenZipSharp\SevenZip\SevenZipExtractorAsynchronous.cs:строка 36
в SevenZip.SevenZipExtractor.DisposedCheck() в C:\projects\SevenZipSharp\SevenZip\SevenZipExtractor.cs:строка 352
в SevenZip.SevenZipExtractor.ExtractArchive(String directory) в C:\projects\SevenZipSharp\SevenZip\SevenZipExtractor.cs:строка 1270

@squid-box
Copy link
Owner

I'm unable to reproduce the error, but your code snippet also seems incomplete - if you're calling BeginExtractArchive you'll need to ensure it's finished before continuing.

The error you're getting, as it states occurs because the stream returns false on either CanSeek or CanRead - both of which are needed to extract files from it. A common cause for these to be false is if the stream is already closed.

I'd check if the file you're trying to use is available to you and that the FileStream is still open.
Also which version of 7z.dll are you using?

@altbodhi
Copy link
Author

altbodhi commented Sep 26, 2018 via email

@squid-box
Copy link
Owner

7z 9.22 is almost 7.5 years old, I'd try with 18.05 (which is the only one I'll attempt to support, until a newer version is released).

I'd also suggest using something like this:

using (var zipStream = new FileStream(@"c:\backup\file.zip", FileMode.Open))
{
    using (var z = new SevenZipExtractor(zipStream, "pass"))
    {
        z.ExtractArchive(@"c:\tmp\test_ext");
    }
}

Unless you're actually handling the asynchronous part outside of your snippet.

@altbodhi
Copy link
Author

I have tried 7z 18.5 but still i have same error.
Yes, of course, i will do it with sync method.

Full code:

            var done = false;
            void Extract()
            {
             
            var zipStream = new FileStream("c:\\backup\\001_documents.zip", FileMode.Open);
            SevenZip.SevenZipBase.SetLibraryPath("7z.dll");
            var z = new SevenZip.SevenZipExtractor(zipStream, "123");
            z.ArchiveFileNames.ForEach(Console.WriteLine);
             z.ExtractionFinished += (sender, eventArgs) => { done = true; };
             z.BeginExtractArchive("c:\\tmp\\test_ext");
            }

            Extract();
            while (!done)
            {
                Thread.Sleep(1000);
                Application.DoEvents();
            }

            Console.WriteLine("done");

@squid-box
Copy link
Owner

It looks like there's an actual problem with doing asynchronous extraction from a stream (it seems the archive is never extracted), I'll look into it in a while.

In your case, is there a reason you're manually opening a FileStream instead of just passing the file to BeginExtractArchive?

In your code above, change var z = new SevenZip.SevenZipExtractor(zipStream, "123"); to var z = new SevenZip.SevenZipExtractor("c:\\backup\\001_documents.zip", "123"); and remove the zipStream variable. This seems to work for me at least.

@altbodhi
Copy link
Author

Thank you. Yes, We use SevenSharp as part archive utils for a lot of various operations in applications(not only files).
I look at code:

        private void RecreateInstanceIfNeeded()
        {
            if (NeedsToBeRecreated)
            {
                NeedsToBeRecreated = false;
                Stream backupStream = null;
                string backupFileName = null;
                if (String.IsNullOrEmpty(_fileName))
                {
                    backupStream = _inStream;
                }
                else
                {
                    backupFileName = _fileName;
                }
                **CommonDispose(); // here dispose and null _inStream, but backupStream not null !!!**
                if (backupStream == null)
                {
                    Init(backupFileName);
                }
                else
                {
                    Init(backupStream);
                }
            }
        }

I think that it is point where there is a mistake.

@kjbtech
Copy link

kjbtech commented Feb 7, 2022

Same trouble below (attachment is MimePart, from MimeKit library) :

MemoryStream memoryStream = new();
await attachment.Content.DecodeToAsync(memoryStream, cancellationToken);
memoryStream.Seek(0, SeekOrigin.Begin);

if (Path.GetExtension(attachment.ContentType.Name) == ".7z")
{
    SevenZipBase.SetLibraryPath(@"X\7z.dll");
    using (SevenZipExtractor sevenZipExtractor = new(memoryStream))
    {
        for (var i = 0; i < sevenZipExtractor.ArchiveFileData.Count; i++)
        {
            using (MemoryStream memoryStreamForPdf = new())
            {
                ArchiveFileInfo fileInArchive = sevenZipExtractor.ArchiveFileData[i];

                if (MimeTypes.GetMimeType(fileInArchive.FileName) == KnownMimeTypes.Pdf)
                {
                    sevenZipExtractor.ExtractFile(sevenZipExtractor.ArchiveFileData[i].Index, memoryStreamForPdf);

                    // internal process
                }
            }
        }
    }
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants