Unity 工具类 之 WWW/UnityWebRequest 下载压缩文件(zip),解压到本地且加载使用解压数据的简单案例(内也含压缩文件例子) 您所在的位置:网站首页 安卓下载压缩包怎么下载 Unity 工具类 之 WWW/UnityWebRequest 下载压缩文件(zip),解压到本地且加载使用解压数据的简单案例(内也含压缩文件例子)

Unity 工具类 之 WWW/UnityWebRequest 下载压缩文件(zip),解压到本地且加载使用解压数据的简单案例(内也含压缩文件例子)

2024-06-29 13:37| 来源: 网络整理| 查看: 265

Unity 工具类 之 WWW/UnityWebRequest 网络下载压缩文件(zip),解压到本地,且加载使用解压数据的简单案例(内也含压缩文件例子)

 

目录

Unity 工具类 之 WWW/UnityWebRequest 网络下载压缩文件(zip),解压到本地,且加载使用解压数据的简单案例(内也含压缩文件例子)

一、简单介绍

二、实现原理

三、注意事项

四、效果预览

五、实现步骤

六、关键代码

 

一、简单介绍

Unity 工具类,自己整理的一些游戏开发可能用到的模块,单独独立使用,方便游戏开发。

Unity 开发中,压缩文件/文件夹,然后网络从服务器下载压缩包到本地,接着本地解压压缩文件,并且使用其中的压缩包解压的文件的简单案例,方便自己日后类似的使用,如能帮到你,就更好了;如若有不对,还望指教。

 

二、实现原理

1、WWW/UnityWebRequest 获取压缩文件的 bytes 数据流;

2、使用 SharpZipLib 进行压缩文件的解压:

可以直接解压 bytes 数据流

也可以解压 bytes 保存的数据文件(也就是这里的下载的压缩包)

 

三、注意事项

1、由于使用 SharpZipLib 进行解压文件,最好使用是SharpZipLib 其压缩的文件;(同时案例中有压缩代码示例)

2、这里涉及到 SharpZipLib 的库使用

具体SharpZipLib 下载使用可参见:Unity 工具 之 (SharpZipLib) 实现文件Zip的压缩和解压((可代密码)可一次压缩多个文件/文件夹)

 

四、效果预览

 

五、实现步骤

1、打开 Unity,新建空工程

 

2、导入 SharpZipLib 的 dll  支持包

具体SharpZipLib 下载使用可参见:Unity 工具 之 (SharpZipLib) 实现文件Zip的压缩和解压((可代密码)可一次压缩多个文件/文件夹)

 

3、在场景中,添加两个 RawImage,这里测试加载压缩包中的 某张图片

 

4、编写脚本逻辑,实现压缩文件的下载,和解压的指定功能,和测试功能的脚本

 

5、把测试脚本挂载到场景中,并对应赋值

 

6、这里同时测试 SharpZipLib 压缩文件功能,准备要压缩的文件夹和文件

 

7、测试脚本,先进行文件压缩,运行场景,即可在指定位置得到压缩的文件

 

8、修改测试脚本、开启测试网络下载压缩文件,并解压(包括两种方式解压),运行场景,效果如上

 

9、对应文件夹中下载的压缩包,和两种方式解压文件

 

六、关键代码

1、Test_WWWDownloadZipAndUnzip

using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.UI; public class Test_WWWDownloadZipAndUnzip : MonoBehaviour { public RawImage rawImage; public RawImage rawImage1; string url; // Start is called before the first frame update void Start() { // 压缩文件 //Test_Zip(); // 下载解压文件 url = Application.temporaryCachePath + "/tempZip.zip"; wwwUnzip(); wwwBytesUnzip(); } #region zip 为后面测试网络下载zip和解压zip使用 /// /// 打包zip /// void Test_Zip() { // 要打包zip的路径数组 string[] zipPaths = new string[] { @"D:\Tmp\temp\ZIPTest" }; string zipOutputPath = Application.temporaryCachePath + "/tempZip.zip"; Debug.Log("zipOutputPath : " + zipOutputPath); ZipWrapper.Zip(zipPaths, zipOutputPath); } #endregion #region Unzip void wwwUnzip() { string zipPath = Application.temporaryCachePath + "/wwwtempZip.zip"; string exportPath = Application.temporaryCachePath + "/unzip"; string imagePath = exportPath + "/ZIPTest/HipHop.jpg"; WWWDownloadZipAndUnzip.Instance.WWWUnzip(url, zipPath, exportPath,()=> { var tex = new Texture2D(1, 1); var imageData = File.ReadAllBytes(imagePath); tex.LoadImage(imageData); rawImage.texture = tex; }); } void wwwBytesUnzip() { string exportPath = Application.temporaryCachePath + "/unzipWithBytes"; string imagePath = exportPath + "/ZIPTest/HipHop.jpg"; WWWDownloadZipAndUnzip.Instance.WWWBytesUnzip(url, exportPath, ()=> { var tex = new Texture2D(1, 1); var imageData = File.ReadAllBytes(imagePath); tex.LoadImage(imageData); rawImage1.texture = tex; }); } #endregion }

 

2、WWWDownloadZipAndUnzip

using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; public class WWWDownloadZipAndUnzip :MonoSingleton { Action wwwZipOnFinished; Action wwwZipBytesOnFinished; #region www download and unzip /// /// 网络下载保存文件之后,再解压 /// /// /// public void WWWUnzip(string url, string zipPath, string exportPath, Action onFinished) { wwwZipOnFinished = onFinished; StartCoroutine(LoadAndUnzip(url, zipPath, exportPath)); } /// /// 协程网络下载zip,保存,并解压 /// /// /// /// IEnumerator LoadAndUnzip(string url, string zipPath, string exportPath) { Debug.Log("zipPath : " + zipPath); Debug.Log("exportPath : " + exportPath); WWW www = new WWW(url); yield return www; if (www.error != null) { Debug.Log("www.error : " + www.error); } else { var data = www.bytes; File.WriteAllBytes(zipPath, data); ZipWrapper.UnzipFile(zipPath, exportPath); if (wwwZipOnFinished != null) { wwwZipOnFinished(); } // 酌情使用即可 //File.Delete(zipPath); //Directory.Delete(exportPath, true); } } /// /// 网络下载bytes 直接解压成文件 /// /// public void WWWBytesUnzip(string url, string exportPath, Action onFinished) { wwwZipBytesOnFinished = onFinished; //StartCoroutine(LoadAndBytesUnzip(url, exportPath)); StartCoroutine(LoadAndBytesUnzipWithWeb(url, exportPath)); } /// /// 协程网络下载zip,并解压 /// /// /// /// IEnumerator LoadAndBytesUnzip(string url, string exportPath) { Debug.Log("exportPath : " + exportPath); WWW www = new WWW(url); yield return www; if (www.error != null) { Debug.Log("www.error : " + www.error); } else { var data = www.bytes; ZipWrapper.UnzipFile(data, exportPath); if (wwwZipBytesOnFinished != null) { wwwZipBytesOnFinished(); } // 酌情使用即可 //File.Delete(zipPath); //Directory.Delete(exportPath, true); } } /// /// 协程网络下载zip,并解压 /// /// /// /// IEnumerator LoadAndBytesUnzipWithWeb(string url, string exportPath) { Debug.Log("exportPath : " + exportPath); using (UnityWebRequest uwr = UnityWebRequest.Get(url)) { yield return uwr.SendWebRequest(); if (uwr.isHttpError == true || uwr.isNetworkError == true) { Debug.Log("www.error : " + uwr.error); } else { var data = uwr.downloadHandler.data; ZipWrapper.UnzipFile(data, exportPath); if (wwwZipBytesOnFinished != null) { wwwZipBytesOnFinished(); } // 酌情使用即可 //File.Delete(zipPath); //Directory.Delete(exportPath, true); } } } #endregion }

 

3、ZipWrapper

using ICSharpCode.SharpZipLib.Zip; using System.IO; using UnityEngine; public class ZipWrapper : MonoBehaviour { #region ZipCallback public abstract class ZipCallback { /// /// 压缩单个文件或文件夹前执行的回调 /// /// /// 如果返回true,则压缩文件或文件夹,反之则不压缩文件或文件夹 public virtual bool OnPreZip(ZipEntry _entry) { return true; } /// /// 压缩单个文件或文件夹后执行的回调 /// /// public virtual void OnPostZip(ZipEntry _entry) { } /// /// 压缩执行完毕后的回调 /// /// true表示压缩成功,false表示压缩失败 public virtual void OnFinished(bool _result) { } } #endregion #region UnzipCallback public abstract class UnzipCallback { /// /// 解压单个文件或文件夹前执行的回调 /// /// /// 如果返回true,则压缩文件或文件夹,反之则不压缩文件或文件夹 public virtual bool OnPreUnzip(ZipEntry _entry) { return true; } /// /// 解压单个文件或文件夹后执行的回调 /// /// public virtual void OnPostUnzip(ZipEntry _entry) { } /// /// 解压执行完毕后的回调 /// /// true表示解压成功,false表示解压失败 public virtual void OnFinished(bool _result) { } } #endregion /// /// 压缩文件和文件夹 /// /// 文件夹路径和文件名 /// 压缩后的输出路径文件名 /// 压缩密码 /// ZipCallback对象,负责回调 /// 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; } /// /// 解压Zip包 /// /// Zip包的文件路径名 /// 解压输出路径 /// 解压密码 /// UnzipCallback对象,负责回调 /// 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; } } /// /// 解压Zip包 /// /// Zip包字节数组 /// 解压输出路径 /// 解压密码 /// UnzipCallback对象,负责回调 /// 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; } /// /// 解压Zip包 /// /// Zip包输入流 /// 解压输出路径 /// 解压密码 /// UnzipCallback对象,负责回调 /// 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; } /// /// 压缩文件 /// /// 文件路径名 /// 要压缩的文件的父相对文件夹 /// 压缩输出流 /// ZipCallback对象,负责回调 /// 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; } /// /// 压缩文件夹 /// /// 要压缩的文件夹 /// 要压缩的文件夹的父相对文件夹 /// 压缩输出流 /// ZipCallback对象,负责回调 /// 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) { // 排除Unity中可能的 .meta 文件 if (files[index].EndsWith(".meta")==true) { Debug.LogWarning(files[index] + " not to zip"); continue; } 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; } }

 

4、MonoSingleton

using UnityEngine; public abstract class MonoSingleton : MonoBehaviour where T : MonoBehaviour { private static T instance = null; private static readonly object locker = new object(); private static bool bAppQuitting; public static T Instance { get { if (bAppQuitting) { instance = null; return instance; } lock (locker) { if (instance == null) { instance = FindObjectOfType(); if (FindObjectsOfType().Length > 1) { Debug.LogError("不应该存在多个单例!"); return instance; } if (instance == null) { var singleton = new GameObject(); instance = singleton.AddComponent(); singleton.name = "(singleton)" + typeof(T); singleton.hideFlags = HideFlags.None; DontDestroyOnLoad(singleton); } else DontDestroyOnLoad(instance.gameObject); } instance.hideFlags = HideFlags.None; return instance; } } } private void Awake() { bAppQuitting = false; } private void OnDestroy() { bAppQuitting = true; } }

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有