123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- /****************************************************************************
- * Copyright 2019 Nreal Techonology Limited. All rights reserved.
- *
- * This file is part of NRSDK.
- *
- * https://www.nreal.ai/
- *
- *****************************************************************************/
- namespace NRKernal
- {
- using System.IO;
- using UnityEngine;
- using ICSharpCode.SharpZipLib.Zip;
- using System;
- /// <summary> A zip utility. </summary>
- public class ZipUtility
- {
- #region ZipCallback
- /// <summary> A zip callback. </summary>
- public class ZipCallback
- {
- /// <summary> The on pre zip callback. </summary>
- public Action<ZipEntry> OnPreZipCallback;
- /// <summary> The on post zip callback. </summary>
- public Action<ZipEntry> OnPostZipCallback;
- /// <summary> The on finished callback. </summary>
- public Action<bool> OnFinishedCallback;
- /// <summary> Constructor. </summary>
- /// <param name="onprezip"> The onprezip.</param>
- /// <param name="onpostzip"> The onpostzip.</param>
- /// <param name="onfinish"> The onfinish.</param>
- public ZipCallback(Action<ZipEntry> onprezip, Action<ZipEntry> onpostzip, Action<bool> onfinish)
- {
- OnPreZipCallback = onprezip;
- OnPostZipCallback = onpostzip;
- OnFinishedCallback = onfinish;
- }
- /// <summary> Constructor. </summary>
- /// <param name="onfinish"> The onfinish.</param>
- public ZipCallback(Action<bool> onfinish) : this(null, null, onfinish)
- {
- }
- /// <summary> Executes the 'pre zip' action. </summary>
- /// <param name="_entry"> The entry.</param>
- /// <returns> True if it succeeds, false if it fails. </returns>
- public virtual bool OnPreZip(ZipEntry _entry)
- {
- if (OnPreZipCallback != null)
- {
- OnPreZipCallback(_entry);
- }
- return true;
- }
- /// <summary> Executes the 'post zip' action. </summary>
- /// <param name="_entry"> The entry.</param>
- public virtual void OnPostZip(ZipEntry _entry)
- {
- if (OnPostZipCallback != null)
- {
- OnPostZipCallback(_entry);
- }
- }
- /// <summary> Executes the 'finished' action. </summary>
- /// <param name="_result"> True to result.</param>
- public virtual void OnFinished(bool _result)
- {
- if (OnFinishedCallback != null)
- {
- OnFinishedCallback(_result);
- }
- }
- }
- #endregion
- #region UnzipCallback
- /// <summary> An unzip callback. </summary>
- public abstract class UnzipCallback
- {
- /// <summary> The on pre zip callback. </summary>
- public Action<ZipEntry> OnPreZipCallback;
- /// <summary> The on post zip callback. </summary>
- public Action<ZipEntry> OnPostZipCallback;
- /// <summary> The on finished callback. </summary>
- public Action<bool> OnFinishedCallback;
- /// <summary> Constructor. </summary>
- /// <param name="onprezip"> The onprezip.</param>
- /// <param name="onpostzip"> The onpostzip.</param>
- /// <param name="onfinish"> The onfinish.</param>
- public UnzipCallback(Action<ZipEntry> onprezip, Action<ZipEntry> onpostzip, Action<bool> onfinish)
- {
- OnPreZipCallback = onprezip;
- OnPostZipCallback = onpostzip;
- OnFinishedCallback = onfinish;
- }
- /// <summary> Constructor. </summary>
- /// <param name="onfinish"> The onfinish.</param>
- public UnzipCallback(Action<bool> onfinish) : this(null, null, onfinish)
- {
- }
- /// <summary> Executes the 'pre unzip' action. </summary>
- /// <param name="_entry"> The entry.</param>
- /// <returns> True if it succeeds, false if it fails. </returns>
- public virtual bool OnPreUnzip(ZipEntry _entry)
- {
- if (OnPreZipCallback != null)
- {
- OnPreZipCallback(_entry);
- }
- return true;
- }
- /// <summary> Executes the 'post unzip' action. </summary>
- /// <param name="_entry"> The entry.</param>
- public virtual void OnPostUnzip(ZipEntry _entry)
- {
- if (OnPostZipCallback != null)
- {
- OnPostZipCallback(_entry);
- }
- }
- /// <summary> Executes the 'finished' action. </summary>
- /// <param name="_result"> True to result.</param>
- public virtual void OnFinished(bool _result)
- {
- if (OnFinishedCallback != null)
- {
- OnFinishedCallback(_result);
- }
- }
- }
- #endregion
- /// <summary> Zips. </summary>
- /// <param name="_fileOrDirectoryArray"> Array of file or directories.</param>
- /// <param name="_outputPathName"> Full pathname of the output file.</param>
- /// <param name="_password"> (Optional) The password.</param>
- /// <param name="_zipCallback"> (Optional) The zip callback.</param>
- /// <returns> True if it succeeds, false if it fails. </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> Unzip file. </summary>
- /// <param name="_filePathName"> Full pathname of the file file.</param>
- /// <param name="_outputPath"> Full pathname of the output file.</param>
- /// <param name="_password"> (Optional) The password.</param>
- /// <param name="_unzipCallback"> (Optional) The unzip callback.</param>
- /// <returns> True if it succeeds, false if it fails. </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)
- {
- NRDebugger.Error("[ZipUtility.UnzipFile]: " + _e.ToString());
- if (null != _unzipCallback)
- _unzipCallback.OnFinished(false);
- return false;
- }
- }
- /// <summary> Unzip file. </summary>
- /// <param name="_fileBytes"> The file in bytes.</param>
- /// <param name="_outputPath"> Full pathname of the output file.</param>
- /// <param name="_password"> (Optional) The password.</param>
- /// <param name="_unzipCallback"> (Optional) The unzip callback.</param>
- /// <returns> True if it succeeds, false if it fails. </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> Unzip file. </summary>
- /// <param name="_inputStream"> Stream to read data from.</param>
- /// <param name="_outputPath"> Full pathname of the output file.</param>
- /// <param name="_password"> (Optional) The password.</param>
- /// <param name="_unzipCallback"> (Optional) The unzip callback.</param>
- /// <returns> True if it succeeds, false if it fails. </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)
- {
- NRDebugger.Error("[ZipUtility.UnzipFile]: " + _e.ToString());
- if (null != _unzipCallback)
- _unzipCallback.OnFinished(false);
- return false;
- }
- }
- }
- if (null != _unzipCallback)
- _unzipCallback.OnFinished(true);
- return true;
- }
- /// <summary> Zip file. </summary>
- /// <param name="_filePathName"> Full pathname of the file file.</param>
- /// <param name="_parentRelPath"> Full pathname of the parent relative file.</param>
- /// <param name="_zipOutputStream"> The zip output stream.</param>
- /// <param name="_zipCallback"> (Optional) The zip callback.</param>
- /// <returns> True if it succeeds, false if it fails. </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)
- {
- NRDebugger.Error("[ZipUtility.ZipFile]: " + _e.ToString());
- return false;
- }
- finally
- {
- if (null != fileStream)
- {
- fileStream.Close();
- fileStream.Dispose();
- }
- }
- if (null != _zipCallback)
- _zipCallback.OnPostZip(entry);
- return true;
- }
- /// <summary> Zip directory. </summary>
- /// <param name="_path"> Full pathname of the file.</param>
- /// <param name="_parentRelPath"> Full pathname of the parent relative file.</param>
- /// <param name="_zipOutputStream"> The zip output stream.</param>
- /// <param name="_zipCallback"> (Optional) The zip callback.</param>
- /// <returns> True if it succeeds, false if it fails. </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)
- {
- NRDebugger.Error("[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;
- }
- }
- }
|