前言
在 Unity 开发中,ZIP 压缩和解压的应用场景非常广泛,例如:
资源包管理(如 DLC、热更新资源)
日志文件压缩(减少存储占用)
数据存档(保存游戏存档或配置文件)
本文将介绍在 Unity 中如何使用 ICSharpCode.SharpZipLib 进行 ZIP 压缩与解压,并提供一个完整的工具类供大家直接使用。
一、资源链接
链接: Unity Zip压缩插件ICSharpCode.SharpZipLib
二、使用步骤
1.引入库
代码如下(示例):
using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace ATF
{
public class ZipHelper
{
/// <summary>
/// 多个文件或文件夹压缩
/// </summary>
/// <param name="sourcePaths">文件或文件夹名称</param>
/// <param name="zipFilePath">压缩文件夹名称</param>
public static string CompressFilesAndDirectories(string[] sourcePaths, string zipFilePath)
{
try
{
Debug.Log($"开始压缩文件:zipFilePath:{zipFilePath}");
using (FileStream fsOut = File.Create(zipFilePath))
{
using (ZipOutputStream zipStream = new ZipOutputStream(fsOut))
{
foreach (string sourcePath in sourcePaths)
{
Debug.Log($"添加压缩文件:{sourcePath}");
if (Directory.Exists(sourcePath))
{
CompressDirectoryRecursive(sourcePath, zipStream);
}
else if (File.Exists(sourcePath))
{
CompressFile(sourcePath, zipStream);
}
else
{
Console.WriteLine($"Path '{sourcePath}' does not exist.");
}
}
}
}
return "成功";
}
catch (Exception ex)
{
return ex.Message;
}
}
/// <summary>
/// 向压缩文件添加文件
/// </summary>
/// <param name="sourceFilePath"></param>
/// <param name="zipStream"></param>
/// <returns></returns>
private static string CompressFile(string sourceFilePath, ZipOutputStream zipStream)
{
try
{
Debug.Log($"添加压缩 文件 :{sourceFilePath}");
string entryName = Path.GetFileName(sourceFilePath);
Debug.Log($"添加压缩 文件entryName :{entryName}");
ZipEntry newEntry = new ZipEntry(entryName);
zipStream.PutNextEntry(newEntry);
byte[] buffer = new byte[4096];
using (FileStream fsIn = File.OpenRead(sourceFilePath))
{
int sourceBytes;
do
{
sourceBytes = fsIn.Read(buffer, 0, buffer.Length);
zipStream.Write(buffer, 0, sourceBytes);
} while (sourceBytes > 0);
}
return "成功";
}
catch (Exception ex)
{
return ex.Message;
}
}
/// <summary>
/// 向压缩文件添加文件夹
/// </summary>
/// <param name="rootDirectoryPath"></param>
/// <param name="currentDirectoryPath"></param>
/// <param name="zipStream"></param>
/// <returns></returns>
private static string CompressDirectoryRecursive(string sourceDirectoryPath, ZipOutputStream zipStream)
{
try
{
Debug.Log($"添加压缩 文件夹 :{sourceDirectoryPath}");
string[] files = Directory.GetFiles(sourceDirectoryPath, "*", SearchOption.AllDirectories);
string rootDirectoryName = Path.GetFileName(sourceDirectoryPath);
// 添加文件夹本身
ZipEntry rootDirectoryEntry = new ZipEntry(rootDirectoryName + "/");
zipStream.PutNextEntry(rootDirectoryEntry);
// 添加文件夹内的文件和子文件夹
foreach (string file in files)
{
string relativePath = GetRelativePath(sourceDirectoryPath, file);
ZipEntry newEntry = new ZipEntry(rootDirectoryName + "/" + relativePath);
zipStream.PutNextEntry(newEntry);
byte[] buffer = new byte[4096];
using (FileStream fsIn = File.OpenRead(file))
{
int sourceBytes;
while ((sourceBytes = fsIn.Read(buffer, 0, buffer.Length)) > 0)
{
zipStream.Write(buffer, 0, sourceBytes);
}
}
}
return "成功";
}
catch (Exception ex)
{
return ex.Message;
}
}
/// <summary>
/// 解压文件
/// </summary>
/// <param name="zipFilePath">压缩文件地址</param>
/// <param name="extractPath">解压文件夹</param>
/// <returns></returns>
public static string DecompressFile(string zipFilePath, string extractPath)
{
try
{
Debug.Log($"zipFilePath: {zipFilePath}");
if (!Directory.Exists(extractPath))
Directory.CreateDirectory(extractPath);
string entryFileName = "";
using (FileStream fsIn = new FileStream(zipFilePath, FileMode.Open, FileAccess.Read))
{
using (ZipInputStream zipStream = new ZipInputStream(fsIn))
{
ZipEntry entry;
while ((entry = zipStream.GetNextEntry()) != null)
{
entryFileName = Path.Combine(extractPath, entry.Name);
string directoryName = Path.GetDirectoryName(entryFileName);
if (directoryName.Length > 0 && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
if (entry.IsFile)
{
using (FileStream fsOut = File.Create(entryFileName))
{
byte[] buffer = new byte[4096];
int sourceBytes;
while ((sourceBytes = zipStream.Read(buffer, 0, buffer.Length)) > 0)
{
fsOut.Write(buffer, 0, sourceBytes);
}
}
}
}
}
}
Debug.Log("DecompressFile解压成功");
return entryFileName;
}
catch (Exception ex)
{
Debug.LogError($"DecompressFile解压不成功{ex.Message}");
return "不成功" + ex.Message;
}
}
public static string GetRelativePath(string fromPath, string toPath)
{
Uri fromUri = new Uri(fromPath.EndsWith("/") ? fromPath : fromPath + "/");
Uri toUri = new Uri(toPath);
Uri relativeUri = fromUri.MakeRelativeUri(toUri);
return Uri.UnescapeDataString(relativeUri.ToString()).Replace("/", Path.DirectorySeparatorChar.ToString());
}
}
}
2.如何使用
1.压缩文件夹
string folderPath = Application.dataPath + "/TestFolder"; // 需要压缩的目录
string zipPath = Application.dataPath + "/Compressed.zip"; // 目标 ZIP 路径
ZipHelper.CompressFilesAndDirectories(folderPath, zipPath);
2.解压Zip代码如下:
string zipFilePath = Application.dataPath + "/Compressed.zip";
string extractFolderPath = Application.dataPath + "/Extracted";
ZipHelper.DecompressFile(zipFilePath, extractFolderPath);
三、Unity ZIP 压缩的应用场景
在 Unity 开发中,ZIP 压缩和解压的应用场景非常广泛,例如:
1.资源包管理(如 DLC、热更新资源)
1.压缩游戏资源(图片、音频、文本)以减少安装包体积
2.解压 ZIP 资源包(DLC、扩展内容)进行动态加载
2.日志与数据存储
1.记录游戏日志(ZIP 压缩后存储,减少体积)
2.玩家存档(压缩存档数据,减少存储空间)
3.远程更新
1.热更新系统(服务器提供 ZIP 资源包,客户端解压后使用)
2.自动补丁(下载 ZIP 压缩的补丁文件,解压后覆盖原文件)
总结
本文介绍了在 Unity 中如何使用 ICSharpCode.SharpZipLib 进行 ZIP 压缩与解压,并提供了一个完整的工具类,可用于压缩文件、文件夹及解压单个文件或整个 ZIP 资源。
ZIP 压缩可以用于 资源管理、日志存储、远程更新 等多个领域,提高项目的可扩展性和存储效率。如果你的项目有 ZIP 需求,可以直接使用本文的工具类!🚀