Search code examples
c#unity-game-enginesharpziplib

TriLib SharpZipLib.Zip.ZipEntry - Cannot access a closed Stream for GetInputStream()


(This is using Unity 2020.1.4f1 with Trilib 2.0.9 Model Loader)

I'm trying to extract the bytes from a zipStream (to load the bytes[] into a Texture2D.LoadImage() in Unity). How do you do this?

Here's what I have tried and the error I am getting:

I'm getting the error: "Cannot access a closed Stream." for Stream zipStream = zipFile.GetInputStream(e) where e is a ZipEntry from a ZipFile (produced by a closed-source sdk)


 Stream zipStream = zipFile.GetInputStream(e); // error occurs here
 
      tex.LoadImage(ReadFully(zipStream));
      tex.Apply();
 

    public static byte[] ReadFully(Stream input)
    {
        byte[] buffer = new byte[16 * 1024];
        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            return ms.ToArray();
        }
    }

and e is extracted within a loop - if that matters

foreach (ZipEntry e in zipFile)
        {
            if (e.IsFile)
            { ... 

ObjectDisposedException: Cannot access a closed Stream.
System.IO.MemoryStream.Seek (System.Int64 offset, System.IO.SeekOrigin loc) (at <fb001e01371b4adca20013e0ac763896>:0)
ICSharpCode.SharpZipLib.Zip.ZipFile.TestLocalHeader (ICSharpCode.SharpZipLib.Zip.ZipEntry entry, ICSharpCode.SharpZipLib.Zip.ZipFile+HeaderTest tests) (at <1a5a474a643a454ba874ca384c215100>:0)
ICSharpCode.SharpZipLib.Zip.ZipFile.LocateEntry (ICSharpCode.SharpZipLib.Zip.ZipEntry entry) (at <1a5a474a643a454ba874ca384c215100>:0)
ICSharpCode.SharpZipLib.Zip.ZipFile.GetInputStrea


Solution

  • So, we discussed the issue in chat and the problem with ZipFile was, it contained no File Name and no Stream in it. Which technically means, we cannot get stream of the individual files in the ZipFile object.

    Scenario: They were using TriLib and passing the URL of the zip file that was available on a server. What TriLib did was, it fetched the file and information, parsed it in an object and returned the object into a method upon completion.

    The Problem: ZipFile object contained no information regarding the Individual Files and their Stream neither it had a name, so the Name property was coming null. Which means, we couldn't perform any operation on the ZipFile object.

    Solution: We made a custom downloader and downloaded the file onto disk, then passed the downloaded file to the ZipFile constructor, by using this approach, we had all the information inside of a zip file.