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
pilchardDev:
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”
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
Loading assembly failed: “Assets/Plugins/System.IO.Compression.dll”
And it still seems to work, at least in the editor.