com.alicizax.unity.framework/Runtime/ABase/Utility/Utility.Compression.Zip.cs

241 lines
8.7 KiB
C#
Raw Normal View History

2026-03-23 20:01:59 +08:00
using System;
using System.IO;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression;
namespace AlicizaX
{
public static partial class Utility
{
/// <summary>
/// Zip 压缩相关的实用函数。
/// </summary>
public static class Zip
{
private static readonly Crc32 s_Crc32 = new Crc32();
public static bool CompressDirectoryToStream(string folderToZip, Stream stream, string password = null)
{
return CompressDirectoryToZipStream(folderToZip, stream, password) != null;
}
public static ZipOutputStream CompressDirectoryToZipStream(string folderToZip, Stream stream, string password = null)
{
if (!Directory.Exists(folderToZip) || stream == null)
{
return null;
}
ZipOutputStream zipStream = new ZipOutputStream(stream);
zipStream.SetLevel(6);
if (!string.IsNullOrEmpty(password))
{
zipStream.Password = password;
}
if (!CompressDirectoryInternal(folderToZip, zipStream, string.Empty))
{
zipStream.Dispose();
return null;
}
zipStream.Finish();
return zipStream;
}
public static bool CompressDirectory(string folderToZip, string zipFile, string password = null)
{
if (string.IsNullOrEmpty(folderToZip) || string.IsNullOrEmpty(zipFile))
{
return false;
}
folderToZip = folderToZip.TrimEnd(System.IO.Path.DirectorySeparatorChar, '/');
using (FileStream writeStream = new FileStream(zipFile, FileMode.Create, FileAccess.Write, FileShare.Write))
{
return CompressDirectoryToZipStream(folderToZip, writeStream, password) != null;
}
}
public static bool CompressFile(string fileToZip, string zipFile, string password = null)
{
if (!System.IO.File.Exists(fileToZip) || string.IsNullOrEmpty(zipFile))
{
return false;
}
byte[] buffer = System.IO.File.ReadAllBytes(fileToZip);
using (FileStream writeStream = System.IO.File.Create(zipFile))
using (ZipOutputStream zipStream = new ZipOutputStream(writeStream))
{
if (!string.IsNullOrEmpty(password))
{
zipStream.Password = password;
}
ZipEntry entry = new ZipEntry(System.IO.Path.GetFileName(fileToZip))
{
DateTime = DateTime.Now,
Size = buffer.Length
};
s_Crc32.Reset();
s_Crc32.Update(buffer);
entry.Crc = s_Crc32.Value;
zipStream.PutNextEntry(entry);
zipStream.SetLevel(Deflater.BEST_COMPRESSION);
zipStream.Write(buffer, 0, buffer.Length);
}
return true;
}
public static bool DecompressFile(string fileToUnzip, string zipFolder, string password = null)
{
if (!System.IO.File.Exists(fileToUnzip) || string.IsNullOrEmpty(zipFolder))
{
return false;
}
Directory.CreateDirectory(zipFolder);
using (ZipInputStream zipStream = new ZipInputStream(System.IO.File.OpenRead(fileToUnzip)))
{
if (!string.IsNullOrEmpty(password))
{
zipStream.Password = password;
}
ZipEntry zipEntry;
while ((zipEntry = zipStream.GetNextEntry()) != null)
{
if (zipEntry.IsDirectory || string.IsNullOrEmpty(zipEntry.Name))
{
continue;
}
string relativePath = zipEntry.Name.Replace('/', System.IO.Path.DirectorySeparatorChar);
string outputPath = System.IO.Path.Combine(zipFolder, relativePath);
string directory = System.IO.Path.GetDirectoryName(outputPath);
if (!string.IsNullOrEmpty(directory))
{
Directory.CreateDirectory(directory);
}
using (FileStream fileStream = System.IO.File.Create(outputPath))
{
zipStream.CopyTo(fileStream);
}
}
}
return true;
}
public static byte[] Compress(byte[] content)
{
if (content == null)
{
return null;
}
Deflater compressor = new Deflater();
compressor.SetLevel(Deflater.BEST_COMPRESSION);
compressor.SetInput(content);
compressor.Finish();
using (MemoryStream output = new MemoryStream(content.Length))
{
byte[] buffer = new byte[4096];
while (!compressor.IsFinished)
{
int read = compressor.Deflate(buffer);
output.Write(buffer, 0, read);
}
return output.ToArray();
}
}
public static byte[] Decompress(byte[] content)
{
return content == null ? null : Decompress(content, 0, content.Length);
}
public static byte[] Decompress(byte[] content, int offset, int count)
{
if (content == null)
{
return null;
}
Inflater decompressor = new Inflater();
decompressor.SetInput(content, offset, count);
using (MemoryStream output = new MemoryStream(content.Length))
{
byte[] buffer = new byte[4096];
while (!decompressor.IsFinished)
{
int read = decompressor.Inflate(buffer);
output.Write(buffer, 0, read);
}
return output.ToArray();
}
}
private static bool CompressDirectoryInternal(string folderToZip, ZipOutputStream zipStream, string parentFolderName)
{
if (!string.IsNullOrWhiteSpace(parentFolderName))
{
ZipEntry entry = new ZipEntry(parentFolderName + "/");
zipStream.PutNextEntry(entry);
zipStream.Flush();
}
string[] files = Directory.GetFiles(folderToZip);
foreach (string file in files)
{
byte[] buffer = System.IO.File.ReadAllBytes(file);
string path = System.IO.Path.GetFileName(file);
if (!string.IsNullOrWhiteSpace(parentFolderName))
{
path = parentFolderName + System.IO.Path.DirectorySeparatorChar + System.IO.Path.GetFileName(file);
}
ZipEntry entry = new ZipEntry(path)
{
DateTime = DateTime.Now,
Size = buffer.Length
};
s_Crc32.Reset();
s_Crc32.Update(buffer);
entry.Crc = s_Crc32.Value;
zipStream.PutNextEntry(entry);
zipStream.Write(buffer, 0, buffer.Length);
}
string[] folders = Directory.GetDirectories(folderToZip);
foreach (string folder in folders)
{
string folderName = System.IO.Path.GetFileName(folder);
if (!string.IsNullOrWhiteSpace(parentFolderName))
{
folderName = parentFolderName + System.IO.Path.DirectorySeparatorChar + folderName;
}
if (!CompressDirectoryInternal(folder, zipStream, folderName))
{
return false;
}
}
return true;
}
}
}
}