Reference DLL
ICSharpCode.SharpZipLib.dll SharpZipLib Git samples, src都有
Usage// 只能在Unity的 Coroutine内调用哦
StartCoroutine(_Coroutine());
private IEnumerator _Coroutine()
{
Debug.Log("uncompress enter...");
var zipFile = "x:/xxx/xxx.zip";
var toFolder = "x:/xxx/xxx";
var async = ZipHelper.UncompressToAsync(zipFile, toFolder, true);
async.onProgress = context =>
{
Debug.Log($"uncompress progress percentage:{context.percentage.ToString("0.000")}");
};
async.onComplete = context =>
{
Debug.Log($"uncompress complete complete:{context.complete}");
};
async.onError = context =>
{
Debug.Log($"uncompress error :{context.error.ToString()}");
};
yield return async.Start();
Debug.Log("uncompress exit...");
}
Code
//------------------------------------------------------------------------
// Craeted by Jave.Lin 5/18/2018 1:06:42 PM
//------------------------------------------------------------------------
using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections;
using System.IO;
using UnityEngine;
namespace Assets.Scripts
{
///
/// [des]
/// author : Jave.Lin
/// date : 5/18/2018 1:06:42 PM
///
public static class ZipHelper
{
public static void CompressTo(string folder, string toFile)
{
FastZip zip = new FastZip();
zip.CreateZip(toFile, folder, true, "");
}
public static ZipUncompressAsync UncompressToAsync(string zipFile, string toFolder, bool createdFolder = true)
{
var ret = new ZipUncompressAsync(createdFolder);
ret.context.zipFile = zipFile;
ret.context.toFolder = toFolder;
return ret;
}
public static bool ExtractZip(byte[] zipBytes, string toFolder)
{
try
{
byte[] writeBuffer = new byte[2048];
using (MemoryStream ms = new MemoryStream(zipBytes))
{
using (ZipInputStream zis = new ZipInputStream(ms))
{
ZipEntry entity = null;
while ((entity = zis.GetNextEntry()) != null)
{
if (!string.IsNullOrEmpty(entity.Name))
{
var fileName = Utils.PathCombine(toFolder, entity.Name);
var parent = Path.GetDirectoryName(fileName);
if (!Directory.Exists(parent)) Directory.CreateDirectory(parent);
using (var fs = File.Create(fileName))
{
var size = 0;
while ((size = zis.Read(writeBuffer, 0, writeBuffer.Length)) > 0)
{
fs.Write(writeBuffer, 0, size);
}
}
}
}
}
}
Array.Resize(ref writeBuffer, 0);
return true;
}
catch (Exception)
{
return false;
}
}
}
public delegate void OnZipUncompressProgress(ZipUncompressContext context);
public delegate void OnZipUncompressComplete(ZipUncompressContext context);
public delegate void OnZipUncompressError(ZipUncompressContext context);
public struct ZipUncompressContext
{
public string zipFile;
public string toFolder;
public float percentage;
public bool done;
public bool isError;
public Exception error;
}
public class ZipUncompressAsync
{
public OnZipUncompressProgress onProgress;
public OnZipUncompressComplete onComplete;
public OnZipUncompressError onError;
public ZipUncompressContext context;
private bool createdFolder;
public ZipUncompressAsync(bool createdFolder = true)
{
this.createdFolder = createdFolder;
context = new ZipUncompressContext();
}
public IEnumerator Start()
{
if (createdFolder)
{
if (!Directory.Exists(context.toFolder))
{
Directory.CreateDirectory(context.toFolder);
}
}
#if UNITY_ANDROID && !UNITY_EDITOR
var saReader = Utils.GetMgr().LoadByURI(context.zipFile);
yield return saReader.Start();
if (saReader.pError != null)
{
context.done = true;
context.error = saReader.pError;
context.isError = true;
onError?.Invoke(context);
yield break;
}
//// 这种方式在android下会报错,改用:ZipHelper.ExtractZip,原因不明
//using (var ms = new MemoryStream(saReader.pData))
//{
// var events = new FastZipEvents();
// events.ProgressInterval = TimeSpan.FromSeconds(0.1f);
// events.Progress = (sender, e) =>
// {
// context.percentage = e.PercentComplete;
// onProgress?.Invoke(context);
// };
// events.CompletedFile = (sender, e) =>
// {
// events.Progress = null;
// events.CompletedFile = null;
// events.FileFailure = null;
// events.DirectoryFailure = null;
// context.done = true;
// onComplete?.Invoke(context);
// };
// events.FileFailure = (sender, e) =>
// {
// events.Progress = null;
// events.CompletedFile = null;
// events.FileFailure = null;
// events.DirectoryFailure = null;
// context.done = true;
// context.error = e.Exception;
// context.isError = true;
// onError?.Invoke(context);
// };
// events.DirectoryFailure = (sender, e) =>
// {
// events.Progress = null;
// events.CompletedFile = null;
// events.FileFailure = null;
// events.DirectoryFailure = null;
// context.done = true;
// context.error = e.Exception;
// context.isError = true;
// onError?.Invoke(context);
// };
// FastZip zip = new FastZip(events);
// zip.ExtractZip(ms, context.toFolder, FastZip.Overwrite.Always, (s) => false, "", "", false, false);
//}
ZipHelper.ExtractZip(saReader.pData, context.toFolder);
context.done = true;
#else
var events = new FastZipEvents();
events.ProgressInterval = TimeSpan.FromSeconds(0.1f);
events.Progress = (sender, e) =>
{
context.percentage = e.PercentComplete;
onProgress?.Invoke(context);
};
events.CompletedFile = (sender, e) =>
{
events.Progress = null;
events.CompletedFile = null;
events.FileFailure = null;
events.DirectoryFailure = null;
context.done = true;
onComplete?.Invoke(context);
};
events.FileFailure = (sender, e) =>
{
events.Progress = null;
events.CompletedFile = null;
events.FileFailure = null;
events.DirectoryFailure = null;
context.done = true;
context.error = e.Exception;
context.isError = true;
onError?.Invoke(context);
};
events.DirectoryFailure = (sender, e) =>
{
events.Progress = null;
events.CompletedFile = null;
events.FileFailure = null;
events.DirectoryFailure = null;
context.done = true;
context.error = e.Exception;
context.isError = true;
onError?.Invoke(context);
};
FastZip zip = new FastZip(events);
zip.ExtractZip(context.zipFile, context.toFolder, "");
#endif
while (!context.done)
{
yield return null;
}
}
}
}