Search Unity

Extracting zip files

Discussion in 'Scripting' started by pilchardDev, May 24, 2017.

  1. pilchardDev

    pilchardDev

    Joined:
    Aug 20, 2016
    Posts:
    40
    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
    Code (CSharp):
    1. System.IO.Compression.ZipFile("zipdir", "todir");
    And unity is saying
    "error CS0103: The name `ZipFile' does not exist in the current context"
     
    Last edited: May 24, 2017
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    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?
     
  3. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    Just curious, but is there a reason you need zip files instead of using asset bundles?
     
  4. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,089
    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 https://github.com/icsharpcode/SharpZipLib/tree/master/src/ICSharpCode.SharpZipLib to somewhere in your project) before but the API is a bit convoluted. You would use it like this (very roughly):

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System;
    4. using System.IO;
    5. using System.Collections;
    6. using ICSharpCode.SharpZipLib.Core;
    7. using ICSharpCode.SharpZipLib.Zip;
    8.  
    9. void LoadZipFile( string FilePath )
    10. {
    11.    if( System.IO.File.Exists( FilePath ) == false )
    12.        return;
    13.  
    14.    // Read file
    15.    FileStream fs = null;
    16.    try
    17.    {
    18.        fs = new FileStream( FilePath , FileMode.Open );
    19.    }
    20.    catch
    21.    {
    22.        Debug.Log( "GameData file open exception: " + FilePath );
    23.    }
    24.  
    25.    if( fs != null )
    26.    {
    27.        try
    28.        {
    29.            // Read zip file
    30.            ZipFile zf = new ZipFile(fs);
    31.            int numFiles = 0;
    32.          
    33.            if( zf.TestArchive( true ) == false )
    34.            {
    35.                Debug.Log( "Zip file failed integrity check!" );
    36.                zf.IsStreamOwner = false;
    37.                zf.Close();
    38.                fs.Close();
    39.            }
    40.            else
    41.            {
    42.                foreach( ZipEntry zipEntry in zf )
    43.                {
    44.                    // Ignore directories
    45.                    if( !zipEntry.IsFile )
    46.                        continue;        
    47.                  
    48.                    String entryFileName = zipEntry.Name;
    49.                  
    50.                    // Skip .DS_Store files (these appear on OSX)
    51.                    if( entryFileName.Contains( "DS_Store" ) )
    52.                        continue;
    53.                  
    54.                    Debug.Log( "Unpacking zip file entry: " + entryFileName );
    55.                  
    56.                    byte[] buffer = new byte[ 4096 ];     // 4K is optimum
    57.                    Stream zipStream = zf.GetInputStream( zipEntry );
    58.  
    59.                    // Manipulate the output filename here as desired.
    60.                    string fullZipToPath = "c:\\" + Path.GetFileName( entryFileName );
    61.  
    62.                    // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
    63.                    // of the file, but does not waste memory.
    64.                    // The "using" will close the stream even if an exception occurs.
    65.                    using (FileStream streamWriter = File.Create(fullZipToPath))
    66.                    {
    67.                        StreamUtils.Copy(zipStream, streamWriter, buffer);
    68.                    }
    69.                    numFiles++;
    70.                }
    71.  
    72.                zf.IsStreamOwner = false;
    73.                zf.Close();
    74.                fs.Close();
    75.            }
    76.        }
    77.        catch
    78.        {
    79.            Debug.Log( "Zip file error!" );
    80.        }
    81.    }
    82. }
    83.  
    84.  
     
    Last edited: Aug 3, 2020
  5. marouane01

    marouane01

    Joined:
    May 22, 2014
    Posts:
    3
    it is possible to stream (get data) from a zip file
     
  6. deadlyGolum

    deadlyGolum

    Joined:
    Dec 31, 2013
    Posts:
    8
    @tonemcbride what if my zip file has directories and files both. And inside those directories, there are files.
    please help
     
  7. Cyber-Dog

    Cyber-Dog

    Joined:
    Sep 12, 2018
    Posts:
    352
    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
    Code (CSharp):
    1. -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.
     
  8. Cyber-Dog

    Cyber-Dog

    Joined:
    Sep 12, 2018
    Posts:
    352
    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.

    Code (CSharp):
    1. -r:System.Net.Http.dll
    2. -r:System.Drawing.dll
    3. -r:System.IO.Compression.FileSystem.dll
     
    Zenix and El-Nacho like this.
  9. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,089
    Hi @deadlyGolum , it's not something I've done before but it should be fairly straightforward. In this code here: https://howtodoinjava.com/java/io/unzip-file-with-subdirectories/ 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.
     
  10. Akhrorjon

    Akhrorjon

    Joined:
    Dec 24, 2019
    Posts:
    3
    • 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
    Code (CSharp):
    1. -r:System.IO.Compression.dll
    2. -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)
     
    albakio and HarvesteR like this.
  11. albakio

    albakio

    Joined:
    Jul 27, 2020
    Posts:
    1
    did not work for me
     
  12. MaxLohMusic

    MaxLohMusic

    Joined:
    Jan 17, 2022
    Posts:
    67
    Loading assembly failed: "Assets/Plugins/System.IO.Compression.dll"

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