SevenZipSharp icon indicating copy to clipboard operation
SevenZipSharp copied to clipboard

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

Open altbodhi opened this issue 7 years ago • 7 comments

       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

altbodhi avatar Sep 26 '18 06:09 altbodhi

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?

squid-box avatar Sep 26 '18 10:09 squid-box

7z.dll x86 version 9.22

ср, 26 сент. 2018 г., 17:35 Joel Ahlgren [email protected]:

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?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/squid-box/SevenZipSharp/issues/25#issuecomment-424667935, or mute the thread https://github.com/notifications/unsubscribe-auth/AXOMwSFinm3Dvo-st9vItC9YE3CEoxUEks5ue1iJgaJpZM4W59wF .

altbodhi avatar Sep 26 '18 10:09 altbodhi

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.

squid-box avatar Sep 26 '18 10:09 squid-box

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");

altbodhi avatar Sep 26 '18 13:09 altbodhi

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.

squid-box avatar Sep 26 '18 20:09 squid-box

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.

altbodhi avatar Sep 27 '18 01:09 altbodhi

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
                }
            }
        }
    }
}

kjbtech avatar Feb 07 '22 08:02 kjbtech