Extracting zip files

Hello, I’m trying to extract a zip file to a certain path with C#. I have no clue how to do so. I’ve tried a few tutorials and guides. had a try of solutions on other posts, and nothing works.

Is anybody able to help? Thanks

Kind Regards, Lachlan

UPDATE: I added the System.IO.FileSystem reference and tried

System.IO.Compression.ZipFile("zipdir", "todir");

And unity is saying
“error CS0103: The name `ZipFile’ does not exist in the current context”

When I looked that up on its docs, it said available since .Net 4.5, so that’s probably why it doesn’t work with Unity currently. What about if you execute a winzip process from inside your game/app?

Just curious, but is there a reason you need zip files instead of using asset bundles?

If you just want to zip/unzip data you can Unity’s built in zip compression (using Unity.IO.Compression and GZipStream).

Alternatively there’s various C# libs for zip files you can use - I’ve had success with ICSharpCode.SharpZipLib.Zip (copy the folders from SharpZipLib/src/ICSharpCode.SharpZipLib at master · icsharpcode/SharpZipLib · GitHub to somewhere in your project) before but the API is a bit convoluted. You would use it like this (very roughly):

using UnityEngine;
using System;
using System.IO;
using System.Collections;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;

void LoadZipFile( string FilePath )
{
   if( System.IO.File.Exists( FilePath ) == false )
       return;

   // Read file
   FileStream fs = null;
   try
   {
       fs = new FileStream( FilePath , FileMode.Open );
   }
   catch
   {
       Debug.Log( "GameData file open exception: " + FilePath );
   }
 
   if( fs != null )
   {
       try
       {
           // Read zip file
           ZipFile zf = new ZipFile(fs);
           int numFiles = 0;
         
           if( zf.TestArchive( true ) == false )
           {
               Debug.Log( "Zip file failed integrity check!" );
               zf.IsStreamOwner = false;
               zf.Close();
               fs.Close();
           }
           else
           {
               foreach( ZipEntry zipEntry in zf )
               {
                   // Ignore directories
                   if( !zipEntry.IsFile )
                       continue;         
                 
                   String entryFileName = zipEntry.Name;
                 
                   // Skip .DS_Store files (these appear on OSX)
                   if( entryFileName.Contains( "DS_Store" ) )
                       continue;
                 
                   Debug.Log( "Unpacking zip file entry: " + entryFileName );
                 
                   byte[] buffer = new byte[ 4096 ];     // 4K is optimum
                   Stream zipStream = zf.GetInputStream( zipEntry );

                   // Manipulate the output filename here as desired.
                   string fullZipToPath = "c:\\" + Path.GetFileName( entryFileName );

                   // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
                   // of the file, but does not waste memory.
                   // The "using" will close the stream even if an exception occurs.
                   using (FileStream streamWriter = File.Create(fullZipToPath))
                   {
                       StreamUtils.Copy(zipStream, streamWriter, buffer);
                   }
                   numFiles++;
               }

               zf.IsStreamOwner = false;
               zf.Close();
               fs.Close();
           }
       }
       catch
       {
           Debug.Log( "Zip file error!" );
       }
   }
}
7 Likes

it is possible to stream (get data) from a zip file

@tonemcbride what if my zip file has directories and files both. And inside those directories, there are files.
please help

Hey this is easy, but not well known for unity.

Firstly go to your player settings and make sure your targeting .net4.X
Then open notepad and add this line

-r:System.IO.Compression.FileSystem.dll

Save it to your root assets folder as “mcs.rsp”

You may have to reload Unity, or create a dummy CS file to force VS to recompile the assemly.

4 Likes

Just an extra note, you can do this for any .net dll that Unity doesn’t target by default. For example, this is what I am targeting in my current project.

-r:System.Net.Http.dll
-r:System.Drawing.dll
-r:System.IO.Compression.FileSystem.dll
2 Likes

Hi @deadlyGolum , it’s not something I’ve done before but it should be fairly straightforward. In this code here: Java Unzip File with Sub-directories you can see a java example of how it works.

In my code it checks for ‘zipEntry.IsFile’ and if it isn’t a file it gets skipped. You could change that to check for a directory and create the directory if it finds one.

  • when targeting the .NET 3.5 Equivalent (deprecated) scripting runtime version, mcs is used with mcs.rsp, and

  • when targeting the .NET 4.x Eqivalent scripting runtime version compiler, csc is used with csc.rsp.

Open notepad and add this line

-r:System.IO.Compression.dll
-r:System.IO.Compression.FileSystem.dll

Save it to your root assets folder as mcs.rsp/csc.rsp depending on .NET version
Reload Unity and Editor, just in case)

2 Likes

did not work for me

Loading assembly failed: “Assets/Plugins/System.IO.Compression.dll”

And it still seems to work, at least in the editor.