Unity3d熱更新(四):壓縮文件

之前提到過通過AssetBundle.CreateFromFile讀取本地AssetBundle,因爲該方法只能讀取未壓縮的AssetBundle,所以打包AssetBundle時,需要選擇BuildAssetBundleOptions.UncompressedAssetBundle未壓縮模式,然後使用LZMA或GZIP壓縮後上傳服務器。本地下載後需要解壓縮保存在Application.persistentDataPath目錄下。

下面說明如何壓縮AssetBundle。

首先需要下載7-zip的C#核心文件,下載地址http://www.7-zip.org/sdk.html


解壓後將CS文件夾下的7zip文件夾導入Unity工程,下面是一個Demo,可以直接用。

[csharp] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. using UnityEngine;  

  2. using System.Collections;  

  3. using UnityEditor;  

  4. using SevenZip.Compression.LZMA;  

  5. using System.IO;  

  6. using System;  

  7.   

  8. // 壓縮或解壓文件  

  9. public class CompressAndDecompress : Editor {  

  10.   

  11.     // 壓縮Unity3D文件  

  12.     [MenuItem("Compress/Compress Unity3D File")]  

  13.     static void CompressUnity3DFile()  

  14.     {  

  15.         string path = EditorUtility.OpenFilePanel("Compress file""""unity3d");  

  16.         CompressFile(path);  

  17.     }  

  18.   

  19.     // 壓縮Lua文件  

  20.     [MenuItem("Compress/Compress Lua File")]  

  21.     static void CompressLuaFile()  

  22.     {  

  23.         string path = EditorUtility.OpenFilePanel("Compress file""""lua");  

  24.         CompressFile(path);  

  25.     }  

  26.   

  27.     // 壓縮文件  

  28.     static void CompressFile(string path)  

  29.     {  

  30.         if (path.Length != 0)  

  31.         {  

  32.             int lastDotIndex = path.LastIndexOf(".");  

  33.             string outputPath = path.Substring(0, lastDotIndex + 1) + "zip";  

  34.             CompressFileLZMA(path, outputPath);  

  35.             AssetDatabase.Refresh();  

  36.             EditorUtility.DisplayDialog("壓縮文件""文件已壓縮完成""確認");  

  37.         }  

  38.     }  

  39.   

  40.     // 解壓Unity3D文件  

  41.     [MenuItem("Compress/Decompress Unity3D File")]  

  42.     static void DecompressUnity3DFile()  

  43.     {  

  44.         DecompressFile("unity3d");  

  45.     }  

  46.   

  47.     // 解壓Lua文件  

  48.     [MenuItem("Compress/Decompress Lua File")]  

  49.     static void DecompressLuaFile()  

  50.     {  

  51.         DecompressFile("lua");  

  52.     }  

  53.   

  54.     static void DecompressFile(string extension)  

  55.     {  

  56.         string path = EditorUtility.OpenFilePanel("Decompress file""""zip");  

  57.   

  58.         if (path.Length != 0)  

  59.         {  

  60.             int lastDotIndex = path.LastIndexOf(".");  

  61.             string outputPath = path.Substring(0, lastDotIndex + 1) + extension;  

  62.             DecompressFileLZMA(path, outputPath);  

  63.             AssetDatabase.Refresh();  

  64.             EditorUtility.DisplayDialog("解壓文件""文件已解壓完成""確認");  

  65.         }  

  66.     }  

  67.   

  68.     // 壓縮文件夾中的文件  

  69.     [MenuItem("Compress/Compress Files In Directory")]  

  70.     static void CompressFilesInDirectory()  

  71.     {  

  72.         string path = EditorUtility.OpenFolderPanel("Compress Files In Directory""""");  

  73.   

  74.         if (path.Length != 0)  

  75.         {  

  76.             DirectoryInfo source = new DirectoryInfo(path);  

  77.             DirectoryInfo target = new DirectoryInfo(path + "_compress");  

  78.   

  79.             if (target.Exists)  

  80.             {  

  81.                 target.Delete(true);  

  82.             }  

  83.   

  84.             target.Create();  

  85.             target.Refresh();  

  86.   

  87.             // 複製源文件夾到目標文件夾  

  88.             CopyAll(source, target);  

  89.             ListFiles((FileSystemInfo)target, true);  

  90.             EditorUtility.DisplayDialog("壓縮文件夾""文件夾中所有的文件已壓縮完成""確認");  

  91.         }  

  92.     }  

  93.   

  94.     // 解壓文件夾中的文件  

  95.     //[MenuItem("Compress/Decompress Files In Directory")]  

  96.     static void DecompressFilesInDirectory()  

  97.     {  

  98.         string path = EditorUtility.OpenFolderPanel("Decompress Files In Directory""""");  

  99.   

  100.         if (path.Length != 0)  

  101.         {  

  102.             DirectoryInfo source = new DirectoryInfo(path);  

  103.             DirectoryInfo target = new DirectoryInfo(path + "_decompress");  

  104.   

  105.             if (target.Exists)  

  106.             {  

  107.                 target.Delete(true);  

  108.             }  

  109.   

  110.             target.Create();  

  111.             target.Refresh();  

  112.   

  113.             // 複製源文件夾到目標文件夾  

  114.             CopyAll(source, target);  

  115.             ListFiles(target, false);  

  116.             EditorUtility.DisplayDialog("解壓文件夾""文件夾中所有的文件已解壓完成""確認");  

  117.         }  

  118.     }  

  119.   

  120.     // 使用LZMA算法壓縮文件  

  121.     private static void CompressFileLZMA(string inFile, string outFile)  

  122.     {  

  123.         Encoder coder = new Encoder();  

  124.         FileStream input = new FileStream(inFile, FileMode.Open);  

  125.         FileStream output = new FileStream(outFile, FileMode.Create);  

  126.   

  127.         coder.WriteCoderProperties(output);  

  128.   

  129.         byte[] data = BitConverter.GetBytes(input.Length);  

  130.   

  131.         output.Write(data, 0, data.Length);  

  132.   

  133.         coder.Code(input, output, input.Length, -1, null);  

  134.         output.Flush();  

  135.         output.Close();  

  136.         input.Close();  

  137.     }  

  138.   

  139.     // 使用LZMA算法解壓文件  

  140.     private static void DecompressFileLZMA(string inFile, string outFile)  

  141.     {  

  142.         Decoder coder = new Decoder();  

  143.         FileStream input = new FileStream(inFile, FileMode.Open);  

  144.         FileStream output = new FileStream(outFile, FileMode.Create);  

  145.   

  146.         byte[] properties = new byte[5];  

  147.         input.Read(properties, 0, 5);  

  148.   

  149.         byte[] fileLengthBytes = new byte[8];  

  150.         input.Read(fileLengthBytes, 0, 8);  

  151.         long fileLength = BitConverter.ToInt64(fileLengthBytes, 0);  

  152.   

  153.         coder.SetDecoderProperties(properties);  

  154.         coder.Code(input, output, input.Length, fileLength, null);  

  155.         output.Flush();  

  156.         output.Close();  

  157.         input.Close();  

  158.     }  

  159.   

  160.     // 複製源文件夾到目標文件夾  

  161.     public static void CopyAll(DirectoryInfo source, DirectoryInfo target, ArrayList extensions = null)  

  162.     {  

  163.         if (source.FullName.ToLower() == target.FullName.ToLower())  

  164.         {  

  165.             return;  

  166.         }  

  167.   

  168.         // 檢測目標文件是否存在,如果不存在,則創建  

  169.         if (!Directory.Exists(target.FullName))  

  170.         {  

  171.             Directory.CreateDirectory(target.FullName);  

  172.             target.Refresh();  

  173.         }  

  174.   

  175.         // 複製文件至目標文件夾  

  176.         foreach (FileInfo fi in source.GetFiles())  

  177.         {  

  178.             if (extensions == null || extensions.Count == 0)  

  179.             {  

  180.                 if (fi.Extension != ".meta")  

  181.                 {  

  182.                     fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);  

  183.                 }  

  184.             }  

  185.             else  

  186.             {  

  187.                 if (extensions.Contains(fi.Extension))  

  188.                 {  

  189.                     fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);  

  190.                 }  

  191.             }  

  192.               

  193.         }  

  194.   

  195.         // 使用遞歸複製子文件夾  

  196.         foreach (DirectoryInfo sourceSubDir in source.GetDirectories())  

  197.         {  

  198.             DirectoryInfo targetSubDir = target.CreateSubdirectory(sourceSubDir.Name);  

  199.             CopyAll(sourceSubDir, targetSubDir, extensions);  

  200.         }  

  201.     }  

  202.   

  203.     // 遍歷文件夾中的所有文件,壓縮或解壓縮  

  204.     public static void ListFiles(FileSystemInfo info, bool isCompress)  

  205.     {  

  206.         if (!info.Exists)  

  207.         {  

  208.             return;  

  209.         }  

  210.   

  211.         DirectoryInfo dir = info as DirectoryInfo;  

  212.   

  213.         // 不是目錄  

  214.         if (dir == null)  

  215.         {  

  216.             return;  

  217.         }  

  218.   

  219.         FileSystemInfo[] files = dir.GetFileSystemInfos();  

  220.   

  221.         for (int i = 0; i < files.Length; i++)  

  222.         {  

  223.             FileInfo file = files[i] as FileInfo;  

  224.   

  225.             // 是文件  

  226.             if (file != null)  

  227.             {  

  228.                 string fullName = file.FullName;  

  229.   

  230.                 // 如果是壓縮文件  

  231.                 if (isCompress)  

  232.                 {  

  233.                     if (file.Extension == ".unity3d" || file.Extension == ".lua")  

  234.                     {  

  235.                         string outputPath = file.FullName.Replace(file.Extension, ".zip");  

  236.                         CompressFileLZMA(fullName, outputPath);  

  237.                         File.Delete(fullName);  

  238.                     }  

  239.                 }  

  240.                 // 如果是解壓文件  

  241.                 else  

  242.                 {  

  243.                     if (file.Extension == ".zip")  

  244.                     {  

  245.                         string outputPath = file.FullName.Replace(file.Extension, ".unity3d");  

  246.                         DecompressFileLZMA(fullName, outputPath);  

  247.                         File.Delete(fullName);  

  248.                     }  

  249.                 }  

  250.   

  251.             }  

  252.             else  

  253.             {  

  254.                 ListFiles(files[i], isCompress);  

  255.             }  

  256.         }  

  257.     }  

  258. }  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章