位置: 文档库 > C#(.NET) > 文档下载预览

《C#压缩解压帮助类.doc》

1. 下载的文档为doc格式,下载后可用word或者wps进行编辑;

2. 将本文以doc文档格式下载到电脑,方便收藏和打印;

3. 下载后的文档,内容与下面显示的完全一致,下载之前请确认下面内容是否您想要的,是否完整.

点击下载文档

C#压缩解压帮助类.doc

《C#压缩解压帮助类》

在.NET开发中,文件压缩与解压是常见的需求场景,例如数据传输优化、存储空间节省或日志归档等。C#通过`System.IO.Compression`命名空间提供了基础的压缩解压功能,但实际应用中可能需要更灵活的封装。本文将详细介绍如何构建一个完整的C#压缩解压帮助类,涵盖ZIP、GZIP两种主流格式,并支持密码保护、分卷压缩等高级功能。

一、基础压缩解压实现

1.1 ZIP格式压缩

使用`ZipFile`类(需引入`System.IO.Compression.FileSystem`)可快速实现目录或文件的压缩:

using System.IO.Compression;

public static void CompressToZip(string sourcePath, string zipPath)
{
    if (Directory.Exists(sourcePath))
    {
        ZipFile.CreateFromDirectory(sourcePath, zipPath);
    }
    else if (File.Exists(sourcePath))
    {
        string tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
        Directory.CreateDirectory(tempDir);
        File.Move(sourcePath, Path.Combine(tempDir, Path.GetFileName(sourcePath)));
        ZipFile.CreateFromDirectory(tempDir, zipPath);
        Directory.Delete(tempDir, true);
    }
}

1.2 ZIP格式解压

解压操作需处理路径不存在的情况:

public static void ExtractFromZip(string zipPath, string destPath)
{
    if (!Directory.Exists(destPath))
    {
        Directory.CreateDirectory(destPath);
    }
    ZipFile.ExtractToDirectory(zipPath, destPath);
}

1.3 GZIP格式压缩解压

GZIP适用于单文件压缩,通过`GZipStream`实现:

public static void CompressWithGzip(string sourceFile, string destFile)
{
    using (FileStream sourceStream = File.OpenRead(sourceFile))
    using (FileStream destStream = File.Create(destFile))
    using (GZipStream gzipStream = new GZipStream(destStream, CompressionLevel.Optimal))
    {
        sourceStream.CopyTo(gzipStream);
    }
}

public static void DecompressWithGzip(string sourceFile, string destFile)
{
    using (FileStream sourceStream = File.OpenRead(sourceFile))
    using (FileStream destStream = File.Create(destFile))
    using (GZipStream gzipStream = new GZipStream(sourceStream, CompressionMode.Decompress))
    {
        gzipStream.CopyTo(destStream);
    }
}

二、高级功能实现

2.1 密码保护压缩

原生.NET不支持ZIP密码,需借助第三方库如SharpZipLib:

// 安装NuGet包:SharpZipLib
using ICSharpCode.SharpZipLib.Zip;

public static void CompressWithPassword(string sourcePath, string zipPath, string password)
{
    using (FileStream fsOut = File.Create(zipPath))
    using (ZipOutputStream zipStream = new ZipOutputStream(fsOut))
    {
        zipStream.Password = password;
        if (Directory.Exists(sourcePath))
        {
            foreach (string file in Directory.GetFiles(sourcePath))
            {
                AddFileToZip(zipStream, file, "");
            }
        }
        else if (File.Exists(sourcePath))
        {
            AddFileToZip(zipStream, sourcePath, "");
        }
    }
}

private static void AddFileToZip(ZipOutputStream zipStream, string filePath, string entryName)
{
    string entry = string.IsNullOrEmpty(entryName) 
        ? Path.GetFileName(filePath) 
        : Path.Combine(entryName, Path.GetFileName(filePath));
    
    ZipEntry zipEntry = new ZipEntry(entry);
    zipStream.PutNextEntry(zipEntry);
    
    using (FileStream fsReader = File.OpenRead(filePath))
    {
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = fsReader.Read(buffer, 0, buffer.Length)) > 0)
        {
            zipStream.Write(buffer, 0, bytesRead);
        }
    }
    zipStream.CloseEntry();
}

2.2 分卷压缩实现

通过计算文件大小实现分卷:

public static void SplitCompress(string sourcePath, string baseName, long maxSizeBytes)
{
    if (Directory.Exists(sourcePath))
    {
        string tempZip = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".zip");
        ZipFile.CreateFromDirectory(sourcePath, tempZip);
        SplitFile(tempZip, baseName, maxSizeBytes);
        File.Delete(tempZip);
    }
    else if (File.Exists(sourcePath))
    {
        SplitFile(sourcePath, baseName, maxSizeBytes);
    }
}

private static void SplitFile(string sourceFile, string baseName, long maxSizeBytes)
{
    byte[] buffer = new byte[4096];
    long bytesRemaining = new FileInfo(sourceFile).Length;
    int partNumber = 0;
    
    using (FileStream sourceStream = File.OpenRead(sourceFile))
    {
        while (bytesRemaining > 0)
        {
            string partName = $"{baseName}.part{++partNumber}.zip";
            long bytesToWrite = Math.Min(maxSizeBytes, bytesRemaining);
            
            using (FileStream destStream = File.Create(partName))
            {
                int bytesRead;
                long totalBytesWritten = 0;
                
                while (totalBytesWritten  0)
                {
                    destStream.Write(buffer, 0, bytesRead);
                    totalBytesWritten += bytesRead;
                }
            }
            bytesRemaining -= bytesToWrite;
        }
    }
}

三、异常处理与优化

3.1 异常处理机制

压缩解压过程中需处理多种异常:

public static void SafeCompress(string source, string dest)
{
    try
    {
        if (string.IsNullOrWhiteSpace(source))
            throw new ArgumentException("源路径不能为空");
        if (!File.Exists(source) && !Directory.Exists(source))
            throw new FileNotFoundException("源文件或目录不存在");
        
        // 压缩逻辑...
    }
    catch (UnauthorizedAccessException ex)
    {
        Console.WriteLine($"权限不足: {ex.Message}");
    }
    catch (PathTooLongException ex)
    {
        Console.WriteLine($"路径过长: {ex.Message}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"压缩失败: {ex.Message}");
    }
}

3.2 性能优化策略

  • 使用缓冲区减少IO操作
  • 多线程处理大文件
  • 根据文件类型选择压缩级别
// 多线程压缩示例
public static async Task ParallelCompressAsync(string sourceDir, string destZip)
{
    var files = Directory.GetFiles(sourceDir);
    var tasks = new List();
    
    foreach (var file in files)
    {
        tasks.Add(CompressFileAsync(file, destZip));
    }
    
    await Task.WhenAll(tasks);
}

private static async Task CompressFileAsync(string file, string destZip)
{
    // 实现异步压缩逻辑
    await Task.Run(() => 
    {
        // 使用ZipArchive进行异步写入
    });
}

四、完整帮助类实现

综合上述功能,构建完整的`CompressionHelper`类:

public static class CompressionHelper
{
    // ZIP压缩(无密码)
    public static void ZipCompress(string source, string dest)
    {
        if (Directory.Exists(source))
        {
            ZipFile.CreateFromDirectory(source, dest);
        }
        else if (File.Exists(source))
        {
            string tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(tempDir);
            File.Move(source, Path.Combine(tempDir, Path.GetFileName(source)));
            ZipFile.CreateFromDirectory(tempDir, dest);
            Directory.Delete(tempDir, true);
        }
    }

    // ZIP解压
    public static void ZipExtract(string source, string dest)
    {
        Directory.CreateDirectory(dest);
        ZipFile.ExtractToDirectory(source, dest);
    }

    // 带密码的ZIP压缩(需SharpZipLib)
    public static void ZipCompressWithPassword(string source, string dest, string password)
    {
        using (FileStream fsOut = File.Create(dest))
        using (ZipOutputStream zipStream = new ZipOutputStream(fsOut))
        {
            zipStream.Password = password;
            // ...实现同2.1节...
        }
    }

    // GZIP压缩
    public static void GzipCompress(string source, string dest)
    {
        using (FileStream sourceStream = File.OpenRead(source))
        using (FileStream destStream = File.Create(dest))
        using (GZipStream gzipStream = new GZipStream(destStream, CompressionLevel.Optimal))
        {
            sourceStream.CopyTo(gzipStream);
        }
    }

    // 分卷压缩
    public static void SplitCompress(string source, string baseName, long maxSize)
    {
        // ...实现同2.2节...
    }
}

五、实际应用场景

5.1 日志归档系统

每日生成的日志文件可通过定时任务压缩存储:

public class LogArchiver
{
    public void ArchiveDailyLogs(string logDir)
    {
        string today = DateTime.Now.ToString("yyyyMMdd");
        string zipPath = Path.Combine(logDir, $"logs_{today}.zip");
        
        var logFiles = Directory.GetFiles(logDir, "*.log")
            .Where(f => Path.GetFileNameWithoutExtension(f).Contains(today.Substring(0, 6)));
        
        foreach (var file in logFiles)
        {
            CompressionHelper.ZipCompress(file, zipPath);
            File.Delete(file);
        }
    }
}

5.2 大文件传输优化

分卷压缩+断点续传实现:

public class FileTransferService
{
    public void PrepareForTransfer(string filePath, string baseName, long chunkSize)
    {
        CompressionHelper.SplitCompress(filePath, baseName, chunkSize);
    }
    
    public void ReassembleFile(string baseName, string destPath)
    {
        var parts = Directory.GetFiles(Path.GetDirectoryName(baseName), $"{Path.GetFileNameWithoutExtension(baseName)}.part*.zip")
            .OrderBy(f => f);
        
        using (FileStream destStream = File.Create(destPath))
        {
            foreach (var part in parts)
            {
                using (FileStream sourceStream = File.OpenRead(part))
                {
                    sourceStream.CopyTo(destStream);
                }
            }
        }
    }
}

六、测试与验证

6.1 单元测试示例

[TestClass]
public class CompressionTests
{
    [TestMethod]
    public void TestZipCompression()
    {
        string testDir = Path.Combine(Path.GetTempPath(), "TestZip");
        Directory.CreateDirectory(testDir);
        File.WriteAllText(Path.Combine(testDir, "test.txt"), "Hello World");
        
        string zipPath = Path.Combine(Path.GetTempPath(), "test.zip");
        CompressionHelper.ZipCompress(testDir, zipPath);
        
        Assert.IsTrue(File.Exists(zipPath));
        Directory.Delete(testDir, true);
    }
    
    [TestMethod]
    public void TestGzipCompression()
    {
        string sourceFile = Path.Combine(Path.GetTempPath(), "test.dat");
        byte[] data = new byte[1024];
        new Random().NextBytes(data);
        File.WriteAllBytes(sourceFile, data);
        
        string gzipPath = Path.Combine(Path.GetTempPath(), "test.gz");
        CompressionHelper.GzipCompress(sourceFile, gzipPath);
        
        Assert.IsTrue(File.Exists(gzipPath));
        File.Delete(sourceFile);
    }
}

6.2 性能基准测试

使用BenchmarkDotNet对比不同压缩级别:

[MemoryDiagnoser]
public class CompressionBenchmark
{
    private readonly byte[] _testData = new byte[1024 * 1024 * 10]; // 10MB数据
    
    [Benchmark]
    public void OptimalCompression()
    {
        using (MemoryStream ms = new MemoryStream())
        using (GZipStream gzip = new GZipStream(ms, CompressionLevel.Optimal))
        {
            gzip.Write(_testData, 0, _testData.Length);
        }
    }
    
    [Benchmark]
    public void FastestCompression()
    {
        using (MemoryStream ms = new MemoryStream())
        using (GZipStream gzip = new GZipStream(ms, CompressionLevel.Fastest))
        {
            gzip.Write(_testData, 0, _testData.Length);
        }
    }
}

七、常见问题解决方案

7.1 中文路径乱码问题

解决方案:指定编码方式

// 使用ZipArchive时设置编码
public static void ZipWithEncoding(string source, string dest)
{
    using (FileStream fs = File.Create(dest))
    using (ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Create))
    {
        // 添加文件时处理编码
        foreach (var file in Directory.GetFiles(source))
        {
            string entryName = file.Replace(source, "").Trim('\\', '/');
            archive.CreateEntryFromFile(file, entryName, CompressionLevel.Optimal);
        }
    }
}

7.2 大文件内存溢出

解决方案:使用流式处理

public static void StreamCompress(string source, string dest)
{
    using (FileStream sourceStream = File.OpenRead(source))
    using (FileStream destStream = File.Create(dest))
    using (GZipStream gzipStream = new GZipStream(destStream, CompressionLevel.Optimal))
    {
        byte[] buffer = new byte[65536]; // 64KB缓冲区
        int bytesRead;
        while ((bytesRead = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
        {
            gzipStream.Write(buffer, 0, bytesRead);
        }
    }
}

7.3 跨平台兼容性问题

解决方案:检测操作系统并调整路径分隔符

public static string NormalizePath(string path)
{
    return Path.DirectorySeparatorChar == '\\' 
        ? path.Replace('/', '\\') 
        : path.Replace('\\', '/');
}

关键词:C#压缩解压、ZIP格式、GZIP格式、密码保护、分卷压缩、SharpZipLib、性能优化、异常处理、流式处理、跨平台兼容

简介:本文详细介绍了C#中实现文件压缩解压的完整方案,涵盖ZIP/GZIP格式的基础操作,以及密码保护、分卷压缩等高级功能。通过代码示例展示了如何构建健壮的压缩解压帮助类,并提供了性能优化、异常处理和跨平台兼容的解决方案,适用于日志归档、大文件传输等实际开发场景。

《C#压缩解压帮助类.doc》
将本文以doc文档格式下载到电脑,方便收藏和打印
推荐度:
点击下载文档