- Home /
unzip zip file content into directory on iphone
Is there a library that would allow me to unzip a zip file contents to a directory on an iphone. I want to download a zip file then unpack it to a directory. I've seen several examples of using sharpZipLib but not that do the unzipping to a directory -- most just show how to get a single file out of the zip. Also the examples do not mention whether or not this is possible on iphone. Is sharpziplib the best solution for this sort of thing?
There are plenty of libraries you can use to do this. Sticking with your choice, take a look at this article:
https://github.com/icsharpcode/SharpZipLib/wiki/Zip-Samples
In particular, one example shows you how to iterate over the whole contents of an archive and write each file entry.
I've done some CS program$$anonymous$$g but not much. Here's my progress so far. I downloaded the library and put the .net 2.0 dll into the plugins folder. I then made a file called zipit.cs which contains this code example from the website you gave me. I get a compilation error saying the type or namespace name 'FilesStream' could not be found. Are you missing a using directive or assembly reference.
using UnityEngine;
using System.Collections.Generic;
using System;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
public class zipit : $$anonymous$$onoBehaviour
{
public void ExtractZipFile(string archiveFilenameIn, string password, string outFolder) {
ZipFile zf = null;
try {
FileStream fs = File.OpenRead(archiveFilenameIn);
zf = new ZipFile(fs);
if (!String.IsNullOrEmpty(password)) {
zf.Password = password; // AES encrypted entries are handled automatically
}
foreach (ZipEntry zipEntry in zf) {
if (!zipEntry.IsFile) {
continue; // Ignore directories
}
String entryFileName = zipEntry.Name;
// to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName);
// Optionally match entrynames against a selection list here to skip as desired.
// The unpacked length is available in the zipEntry.Size property.
byte[] buffer = new byte[4096]; // 4$$anonymous$$ is optimum
Stream zipStream = zf.GetInputStream(zipEntry);
// $$anonymous$$anipulate the output filename here as desired.
String fullZipToPath = Path.Combine(outFolder, entryFileName);
string directoryName = Path.GetDirectoryName(fullZipToPath);
if (directoryName.Length > 0)
Directory.CreateDirectory(directoryName);
// 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);
}
}
} finally {
if (zf != null) {
zf.IsStreamOwner = true; // $$anonymous$$akes close also shut the underlying stream
zf.Close(); // Ensure we release resources
}
}
}
}
I've updated and added a class now I get a new error. It's at the end of the first paragraph.
Answer by dansav · Nov 10, 2012 at 12:07 AM
Okay with the help of phodges I've got something that works. First download sharpziplib and take the 2.0 dll and put it in your plugins folder. Then create a cs file and label it zipit.cs and paste the code in below. Put in the plugins folder also. Next make a new empty gameObject and drag the zipit.cs script onto it. Then from unity call...the zipit.Zip function. Where my files are all in a folder called StreamingAssets in the Assets folder. The cs file contains routines for zipping and unzipping single files and folders. The cs code was cut and pasted from different projects such as the one listed above and one here. I've tried it and it seems to work in the editor, not sure about iphone yet. These routines require the files to already be in the folders. I really don't know how to answer questions about the code itself since I'm just a novice C# programmer.
http://www.codeproject.com/Articles/20493/Make-a-Zip-UnZip-Software-using-SharpZipLib
//Unity code which can go in any game object.
zipit.Zip(Application.streamingAssetsPath+"/beach.mp4",Application.streamingAssetsPath+"/beach.zip");
Put this in the cs file
using UnityEngine;
using System.Collections.Generic;
using System;
using System.IO;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using System
public class zipit : MonoBehaviour
{
public void ExtractZipFile(string archiveFilenameIn, string password, string outFolder) {
ZipFile zf = null;
try {
FileStream fs = File.OpenRead(archiveFilenameIn);
zf = new ZipFile(fs);
if (!String.IsNullOrEmpty(password)) {
zf.Password = password; // AES encrypted entries are handled automatically
}
foreach (ZipEntry zipEntry in zf) {
if (!zipEntry.IsFile) {
continue; // Ignore directories
}
String entryFileName = zipEntry.Name;
// to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName);
// Optionally match entrynames against a selection list here to skip as desired.
// The unpacked length is available in the zipEntry.Size property.
byte[] buffer = new byte[4096]; // 4K is optimum
Stream zipStream = zf.GetInputStream(zipEntry);
// Manipulate the output filename here as desired.
String fullZipToPath = Path.Combine(outFolder, entryFileName);
string directoryName = Path.GetDirectoryName(fullZipToPath);
if (directoryName.Length > 0)
Directory.CreateDirectory(directoryName);
// 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);
}
}
} finally {
if (zf != null) {
zf.IsStreamOwner = true; // Makes close also shut the underlying stream
zf.Close(); // Ensure we release resources
}
}
}
public void CreateSample(string outPathname, string password, string folderName) {
FileStream fsOut = File.Create(outPathname);
ZipOutputStream zipStream = new ZipOutputStream(fsOut);
zipStream.SetLevel(3); //0-9, 9 being the highest level of compression
zipStream.Password = password; // optional. Null is the same as not setting. Required if using AES.
// This setting will strip the leading part of the folder path in the entries, to
// make the entries relative to the starting folder.
// To include the full path for each entry up to the drive root, assign folderOffset = 0.
int folderOffset = folderName.Length + (folderName.EndsWith("\\") ? 0 : 1);
CompressFolder(folderName, zipStream, folderOffset);
zipStream.IsStreamOwner = true; // Makes the Close also Close the underlying stream
zipStream.Close();
}
// Recurses down the folder structure
//
private void CompressFolder(string path, ZipOutputStream zipStream, int folderOffset) {
string[] files = Directory.GetFiles(path);
foreach (string filename in files) {
FileInfo fi = new FileInfo(filename);
string entryName = filename.Substring(folderOffset); // Makes the name in zip based on the folder
entryName = ZipEntry.CleanName(entryName); // Removes drive from name and fixes slash direction
ZipEntry newEntry = new ZipEntry(entryName);
newEntry.DateTime = fi.LastWriteTime; // Note the zip format stores 2 second granularity
// Specifying the AESKeySize triggers AES encryption. Allowable values are 0 (off), 128 or 256.
// A password on the ZipOutputStream is required if using AES.
// newEntry.AESKeySize = 256;
// To permit the zip to be unpacked by built-in extractor in WinXP and Server2003, WinZip 8, Java, and other older code,
// you need to do one of the following: Specify UseZip64.Off, or set the Size.
// If the file may be bigger than 4GB, or you do not need WinXP built-in compatibility, you do not need either,
// but the zip will be in Zip64 format which not all utilities can understand.
// zipStream.UseZip64 = UseZip64.Off;
newEntry.Size = fi.Length;
zipStream.PutNextEntry(newEntry);
// Zip the file in buffered chunks
// the "using" will close the stream even if an exception occurs
byte[ ] buffer = new byte[4096];
using (FileStream streamReader = File.OpenRead(filename)) {
StreamUtils.Copy(streamReader, zipStream, buffer);
}
zipStream.CloseEntry();
}
string[ ] folders = Directory.GetDirectories(path);
foreach (string folder in folders) {
CompressFolder(folder, zipStream, folderOffset);
}
}
public static void Zip(string SrcFile, string DstFile)
{
FileStream fileStreamIn = new FileStream
(SrcFile, FileMode.Open, FileAccess.Read);
FileStream fileStreamOut = new FileStream
(DstFile, FileMode.Create, FileAccess.Write);
ZipOutputStream zipOutStream = new ZipOutputStream(fileStreamOut);
byte[] buffer = new byte[4096];
ZipEntry entry = new ZipEntry(Path.GetFileName(SrcFile));
zipOutStream.PutNextEntry(entry);
int size;
do
{
size = fileStreamIn.Read(buffer, 0, buffer.Length);
zipOutStream.Write(buffer, 0, size);
} while (size > 0);
zipOutStream.Close();
fileStreamOut.Close();
fileStreamIn.Close();
}
public static void UnZip(string SrcFile, string DstFile)
{
FileStream fileStreamIn = new FileStream
(SrcFile, FileMode.Open, FileAccess.Read);
ZipInputStream zipInStream = new ZipInputStream(fileStreamIn);
ZipEntry entry = zipInStream.GetNextEntry();
FileStream fileStreamOut = new FileStream
(DstFile + @"\" + entry.Name, FileMode.Create, FileAccess.Write);
int size;
byte[] buffer = new byte[4096];
do
{
size = zipInStream.Read(buffer, 0, buffer.Length);
fileStreamOut.Write(buffer, 0, size);
} while (size > 0);
zipInStream.Close();
fileStreamOut.Close();
fileStreamIn.Close();
}
}