使用SharpZipLib庫,下載地址為:http://icsharpcode.github.io/SharpZipLib/
/******************************************************
* DESCRIPTION: Zip包的壓縮與解壓
*
* Copyright (c) 2017, 譚偉俊 (TanWeijun)
* All rights reserved
*
* CREATED: 2017.03.11, 08:37, CST
******************************************************/
using System.IO;
using System.Collections;
using UnityEngine;
using ICSharpCode.SharpZipLib.Zip;
public static class ZipUtility
{
#region ZipCallback
public abstract class ZipCallback
{
/// <summary>
/// 壓縮單個文件或文件夾前執行的回調
/// </summary>
/// <param name="_entry"></param>
/// <returns>如果返回true,則壓縮文件或文件夾,反之則不壓縮文件或文件夾</returns>
public virtual bool OnPreZip(ZipEntry _entry)
{
return true;
}
/// <summary>
/// 壓縮單個文件或文件夾后執行的回調
/// </summary>
/// <param name="_entry"></param>
public virtual void OnPostZip(ZipEntry _entry) {}
/// <summary>
/// 壓縮執行完畢后的回調
/// </summary>
/// <param name="_result">true表示壓縮成功,false表示壓縮失敗</param>
public virtual void OnFinished(bool _result) {}
}
#endregion
#region UnzipCallback
public abstract class UnzipCallback
{
/// <summary>
/// 解壓單個文件或文件夾前執行的回調
/// </summary>
/// <param name="_entry"></param>
/// <returns>如果返回true,則壓縮文件或文件夾,反之則不壓縮文件或文件夾</returns>
public virtual bool OnPreUnzip(ZipEntry _entry)
{
return true;
}
/// <summary>
/// 解壓單個文件或文件夾后執行的回調
/// </summary>
/// <param name="_entry"></param>
public virtual void OnPostUnzip(ZipEntry _entry) {}
/// <summary>
/// 解壓執行完畢后的回調
/// </summary>
/// <param name="_result">true表示解壓成功,false表示解壓失敗</param>
public virtual void OnFinished(bool _result) {}
}
#endregion
/// <summary>
/// 壓縮文件和文件夾
/// </summary>
/// <param name="_fileOrDirectoryArray">文件夾路徑和文件名</param>
/// <param name="_outputPathName">壓縮后的輸出路徑文件名</param>
/// <param name="_password">壓縮密碼</param>
/// <param name="_zipCallback">ZipCallback對象,負責回調</param>
/// <returns></returns>
public static bool Zip( string[] _fileOrDirectoryArray, string _outputPathName, string _password = null, ZipCallback _zipCallback = null)
{
if ((null == _fileOrDirectoryArray) || string.IsNullOrEmpty(_outputPathName))
{
if (null != _zipCallback)
_zipCallback.OnFinished(false);
return false;
}
ZipOutputStream zipOutputStream = new ZipOutputStream(File.Create(_outputPathName));
zipOutputStream.SetLevel(6); // 壓縮質量和壓縮速度的平衡點
if (!string.IsNullOrEmpty(_password))
zipOutputStream.Password = _password;
for (int index = 0; index < _fileOrDirectoryArray.Length; ++index)
{
bool result = false;
string fileOrDirectory = _fileOrDirectoryArray[index];
if (Directory.Exists(fileOrDirectory))
result = ZipDirectory(fileOrDirectory, string.Empty, zipOutputStream, _zipCallback);
else if (File.Exists(fileOrDirectory))
result = ZipFile(fileOrDirectory, string.Empty, zipOutputStream, _zipCallback);
if (!result)
{
if (null != _zipCallback)
_zipCallback.OnFinished(false);
return false;
}
}
zipOutputStream.Finish();
zipOutputStream.Close();
if (null != _zipCallback)
_zipCallback.OnFinished(true);
return true;
}
/// <summary>
/// 解壓Zip包
/// </summary>
/// <param name="_filePathName">Zip包的文件路徑名</param>
/// <param name="_outputPath">解壓輸出路徑</param>
/// <param name="_password">解壓密碼</param>
/// <param name="_unzipCallback">UnzipCallback對象,負責回調</param>
/// <returns></returns>
public static bool UnzipFile(string _filePathName, string _outputPath, string _password = null, UnzipCallback _unzipCallback = null)
{
if (string.IsNullOrEmpty(_filePathName) || string.IsNullOrEmpty(_outputPath))
{
if (null != _unzipCallback)
_unzipCallback.OnFinished(false);
return false;
}
try
{
return UnzipFile(File.OpenRead(_filePathName), _outputPath, _password, _unzipCallback);
}
catch (System.Exception _e)
{
Debug.LogError("[ZipUtility.UnzipFile]: " + _e.ToString());
if (null != _unzipCallback)
_unzipCallback.OnFinished(false);
return false;
}
}
/// <summary>
/// 解壓Zip包
/// </summary>
/// <param name="_fileBytes">Zip包字節數組</param>
/// <param name="_outputPath">解壓輸出路徑</param>
/// <param name="_password">解壓密碼</param>
/// <param name="_unzipCallback">UnzipCallback對象,負責回調</param>
/// <returns></returns>
public static bool UnzipFile(byte[] _fileBytes, string _outputPath, string _password = null, UnzipCallback _unzipCallback = null)
{
if ((null == _fileBytes) || string.IsNullOrEmpty(_outputPath))
{
if (null != _unzipCallback)
_unzipCallback.OnFinished(false);
return false;
}
bool result = UnzipFile(new MemoryStream(_fileBytes), _outputPath, _password, _unzipCallback);
if (!result)
{
if (null != _unzipCallback)
_unzipCallback.OnFinished(false);
}
return result;
}
/// <summary>
/// 解壓Zip包
/// </summary>
/// <param name="_inputStream">Zip包輸入流</param>
/// <param name="_outputPath">解壓輸出路徑</param>
/// <param name="_password">解壓密碼</param>
/// <param name="_unzipCallback">UnzipCallback對象,負責回調</param>
/// <returns></returns>
public static bool UnzipFile(Stream _inputStream, string _outputPath, string _password = null, UnzipCallback _unzipCallback = null)
{
if ((null == _inputStream) || string.IsNullOrEmpty(_outputPath))
{
if (null != _unzipCallback)
_unzipCallback.OnFinished(false);
return false;
}
// 創建文件目錄
if (!Directory.Exists(_outputPath))
Directory.CreateDirectory(_outputPath);
// 解壓Zip包
ZipEntry entry = null;
using (ZipInputStream zipInputStream = new ZipInputStream(_inputStream))
{
if (!string.IsNullOrEmpty(_password))
zipInputStream.Password = _password;
while (null != (entry = zipInputStream.GetNextEntry()))
{
if (string.IsNullOrEmpty(entry.Name))
continue;
if ((null != _unzipCallback) && !_unzipCallback.OnPreUnzip(entry))
continue; // 過濾
string filePathName = Path.Combine(_outputPath, entry.Name);
// 創建文件目錄
if (entry.IsDirectory)
{
Directory.CreateDirectory(filePathName);
continue;
}
// 寫入文件
try
{
using (FileStream fileStream = File.Create(filePathName))
{
byte[] bytes = new byte[1024];
while (true)
{
int count = zipInputStream.Read(bytes, 0, bytes.Length);
if (count > 0)
fileStream.Write(bytes, 0, count);
else
{
if (null != _unzipCallback)
_unzipCallback.OnPostUnzip(entry);
break;
}
}
}
}
catch (System.Exception _e)
{
Debug.LogError("[ZipUtility.UnzipFile]: " + _e.ToString());
if (null != _unzipCallback)
_unzipCallback.OnFinished(false);
return false;
}
}
}
if (null != _unzipCallback)
_unzipCallback.OnFinished(true);
return true;
}
/// <summary>
/// 壓縮文件
/// </summary>
/// <param name="_filePathName">文件路徑名</param>
/// <param name="_parentRelPath">要壓縮的文件的父相對文件夾</param>
/// <param name="_zipOutputStream">壓縮輸出流</param>
/// <param name="_zipCallback">ZipCallback對象,負責回調</param>
/// <returns></returns>
private static bool ZipFile(string _filePathName, string _parentRelPath, ZipOutputStream _zipOutputStream, ZipCallback _zipCallback = null)
{
//Crc32 crc32 = new Crc32();
ZipEntry entry = null;
FileStream fileStream = null;
try
{
string entryName = _parentRelPath + '/' + Path.GetFileName(_filePathName);
entry = new ZipEntry(entryName);
entry.DateTime = System.DateTime.Now;
if ((null != _zipCallback) && !_zipCallback.OnPreZip(entry))
return true; // 過濾
fileStream = File.OpenRead(_filePathName);
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, buffer.Length);
fileStream.Close();
entry.Size = buffer.Length;
//crc32.Reset();
//crc32.Update(buffer);
//entry.Crc = crc32.Value;
_zipOutputStream.PutNextEntry(entry);
_zipOutputStream.Write(buffer, 0, buffer.Length);
}
catch (System.Exception _e)
{
Debug.LogError("[ZipUtility.ZipFile]: " + _e.ToString());
return false;
}
finally
{
if (null != fileStream)
{
fileStream.Close();
fileStream.Dispose();
}
}
if (null != _zipCallback)
_zipCallback.OnPostZip(entry);
return true;
}
/// <summary>
/// 壓縮文件夾
/// </summary>
/// <param name="_path">要壓縮的文件夾</param>
/// <param name="_parentRelPath">要壓縮的文件夾的父相對文件夾</param>
/// <param name="_zipOutputStream">壓縮輸出流</param>
/// <param name="_zipCallback">ZipCallback對象,負責回調</param>
/// <returns></returns>
private static bool ZipDirectory(string _path, string _parentRelPath, ZipOutputStream _zipOutputStream, ZipCallback _zipCallback = null)
{
ZipEntry entry = null;
try
{
string entryName = Path.Combine(_parentRelPath, Path.GetFileName(_path) + '/');
entry = new ZipEntry(entryName);
entry.DateTime = System.DateTime.Now;
entry.Size = 0;
if ((null != _zipCallback) && !_zipCallback.OnPreZip(entry))
return true; // 過濾
_zipOutputStream.PutNextEntry(entry);
_zipOutputStream.Flush();
string[] files = Directory.GetFiles(_path);
for (int index = 0; index < files.Length; ++index)
ZipFile(files[index], Path.Combine(_parentRelPath, Path.GetFileName(_path)), _zipOutputStream, _zipCallback);
}
catch (System.Exception _e)
{
Debug.LogError("[ZipUtility.ZipDirectory]: " + _e.ToString());
return false;
}
string[] directories = Directory.GetDirectories(_path);
for (int index = 0; index < directories.Length; ++index)
{
if (!ZipDirectory(directories[index], Path.Combine(_parentRelPath, Path.GetFileName(_path)), _zipOutputStream, _zipCallback))
return false;
}
if (null != _zipCallback)
_zipCallback.OnPostZip(entry);
return true;
}
}
作者:EnigmaJJ
鏈接:http://www.jianshu.com/p/acc3d79d93f7
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
