首页 > 编程语言 >dotnet C# 简单的追加文件夹到 ZipArchive 压缩文件的方法

dotnet C# 简单的追加文件夹到 ZipArchive 压缩文件的方法

时间:2024-04-26 18:44:21浏览次数:20  
标签:folders C# ZipArchive item 文件夹 var 压缩文件 fileCanAddedPredicate lindexi

本文将告诉大家一个在 ZipArchive 里追加文件夹,以及添加过滤文件处理的压缩文件辅助方法

实现的方法的代码如下

    /// <summary>
    /// 追加文件夹到压缩文件里面
    /// </summary>
    /// <param name="archive"></param>
    /// <param name="sourceDirectoryName"></param>
    /// <param name="zipRelativePath">在压缩包里面的相对路径</param>
    /// <param name="compressionLevel"></param>
    /// <param name="fileCanAddedPredicate"></param>
    public static void AppendDirectoryToZipArchive(ZipArchive archive, string sourceDirectoryName, string zipRelativePath, CompressionLevel compressionLevel = CompressionLevel.Fastest, Predicate<string>? fileCanAddedPredicate = null)
    {
        var folders = new Stack<string>();

        folders.Push(sourceDirectoryName);

        while (folders.Count > 0)
        {
            var currentFolder = folders.Pop();

            foreach (var item in Directory.EnumerateFiles(currentFolder))
            {
                if (fileCanAddedPredicate != null && !fileCanAddedPredicate(item))
                {
                    continue;
                }

                archive.CreateEntryFromFile(item, Path.Join(zipRelativePath, Path.GetRelativePath(sourceDirectoryName, item)), compressionLevel);
            }

            foreach (var item in Directory.EnumerateDirectories(currentFolder))
            {
                folders.Push(item);
            }
        }
    }

演示的调用的代码如下

var zipFile = "1.zip";
using (var fileStream = new FileStream(zipFile, FileMode.Create, FileAccess.Write))
{
    using var zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Create, leaveOpen: true/*自己释放 FileStream 对象*/, Encoding.UTF8);
    Foo.AppendDirectoryToZipArchive(zipArchive, @"C:\lindexi\Library\", "Lib");
    Foo.AppendDirectoryToZipArchive(zipArchive, @"C:\lindexi\CA\", "Pem", fileCanAddedPredicate: filePath =>
    {
        var fileName = Path.GetFileName(filePath);
        return fileName != "foo.ignore.file";
    });
}

支持设置文件夹加入之后在安装包的什么相对路径下,也支持过滤文件

如果加入到安装包的根路径下,只需要让 zipRelativePath 参数传入空字符串即可,如下面代码

    Foo.AppendDirectoryToZipArchive(zipArchive, @"C:\lindexi\Library\", "");

全部的代码如下

using System.IO.Compression;
using System.Text;

var zipFile = "1.zip";
using (var fileStream = new FileStream(zipFile, FileMode.Create, FileAccess.Write))
{
    using var zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Create, leaveOpen: true/*自己释放 FileStream 对象*/, Encoding.UTF8);
    Foo.AppendDirectoryToZipArchive(zipArchive, @"C:\lindexi\Library\", "Lib");
    Foo.AppendDirectoryToZipArchive(zipArchive, @"C:\lindexi\CA\", "Pem", fileCanAddedPredicate: filePath =>
    {
        var fileName = Path.GetFileName(filePath);
        return fileName != "foo.ignore.file";
    });
}


class Foo
{
    /// <summary>
    /// 追加文件夹到压缩文件里面
    /// </summary>
    /// <param name="archive"></param>
    /// <param name="sourceDirectoryName"></param>
    /// <param name="zipRelativePath">在压缩包里面的相对路径</param>
    /// <param name="compressionLevel"></param>
    /// <param name="fileCanAddedPredicate"></param>
    public static void AppendDirectoryToZipArchive(ZipArchive archive, string sourceDirectoryName, string zipRelativePath, CompressionLevel compressionLevel = CompressionLevel.Fastest, Predicate<string>? fileCanAddedPredicate = null)
    {
        var folders = new Stack<string>();

        folders.Push(sourceDirectoryName);

        while (folders.Count > 0)
        {
            var currentFolder = folders.Pop();

            foreach (var item in Directory.EnumerateFiles(currentFolder))
            {
                if (fileCanAddedPredicate != null && !fileCanAddedPredicate(item))
                {
                    continue;
                }

                archive.CreateEntryFromFile(item, Path.Join(zipRelativePath, Path.GetRelativePath(sourceDirectoryName, item)), compressionLevel);
            }

            foreach (var item in Directory.EnumerateDirectories(currentFolder))
            {
                folders.Push(item);
            }
        }
    }
}

以上的 C:\lindexi\Library 等文件夹是我的用于测试的文件夹,还请大家换成自己的文件夹

本文代码放在 githubgitee 上,可以使用如下命令行拉取代码

先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 76bed002b4da4f363037c2d39f41596be1c2b177

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 76bed002b4da4f363037c2d39f41596be1c2b177

获取代码之后,进入 LebenehainaiJelearlowiwaw 文件夹,即可获取到源代码

标签:folders,C#,ZipArchive,item,文件夹,var,压缩文件,fileCanAddedPredicate,lindexi
From: https://www.cnblogs.com/lindexi/p/18160678

相关文章

  • SQLAlchemy中filter()和filter_by()有什么区别
    1.filter用类名.属性名,比较用==,filter_by直接用属性名,比较用=2.filter不支持组合查询,只能连续调用filter来变相实现。session.query(Dashboard).filter(Dashboard.id.in_(dashboard_ids_int)) .all()dashboard=(db.session.query(Dashboard).filter_by(id=dashboard_......
  • lib 安装失败,error Microsoft Visual C++ 14.0 is required.
    即使安装c++要占用c盘4G,而且仍然有可能报错,error:command'C:\ProgramFiles(x86)\MicrosoftVisualStudio14.0\VC\BIN\x86_amd64\cl.exe'failedwithexitstatus2另一种解决方法是直接下载whl,省去编译的过程https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib有可能......
  • C# 将实体2的值动态赋值给实体1(名称一样的属性进行赋值)
     ///<summary>///将实体2的值动态赋值给实体1(名称一样的属性进行赋值)///</summary>///<paramname="model1">实体1</param>///<paramname="model2">实体2</param>///<retur......
  • AGC041F Histogram Rooks
    考察一个合法的棋盘,有一些列上有车,其他的列没有车。有车的列所有格子都被覆盖,没有车的列上的每个格子都需要被同一行的车覆盖。即考察所有极长的行连续段,如果这个连续段涉及的列里包含没有车的列,那么这个行连续段里必须有车。考虑枚举有车的列的集合\(S\),对于每个行连续段,记它......
  • Java并发01---JMM模型、Volatile、CAS操作、自旋锁、ABA问题
    @目录JMM(JavaMemoryModel)Volatile修饰CAS(CompareAndSwap)ABA问题JMM(JavaMemoryModel)首先要明确的是JMM与JVM内存结构不是同一个概念,记的时候不要记混。我们先来回顾一下JVM内存结构,其包括了堆、方法区、虚拟机栈、程序计数器、本地方法区,其中前二者为线程共享,后三者为线程......
  • AI模块(有限状态机、行为树)-应用在cocos中
    前言:本模块是在cocos项目中运用战斗框架,根据学习别人的文章来结合项目进行编写的,若有不对不合理的地方有劳大家指正,万分感谢!!!若有能有用的上的,万分荣幸!简介:AI模块一般是对怪物的AI实现,或者托管等自动战斗的情况。具体方式可能根据项目的具体需求来选择,常用的有:有限状态机,行为树......
  • Java并发02---Synchronized的实现原理、锁的升级、锁的膨胀、对象头、锁的消除、偏向
    @目录何为synchronized前置知识:对象头锁的升级(锁的膨胀)偏向锁轻量级锁轻量级锁锁的消除何为synchronized我们知道,synchronized关键字能够将其修饰的代码块、方法、静态方法变成同步代码。我们在前文中已经介绍过了,使用volatile关键字修饰能保证变量在内存中的可见性,但不保证操作......
  • C# Modbut TCP 读写
    一、封装基本连接、读写。读写 ReadHoldingRegisters,当前有四种方案,现在只使用 ReadHoldingRegistersint类型,需要其他方案自行新增。publicclassModbusClient{privateTcpClient?tcpClient;privateIModbusMaster?modbusMaster;......
  • Nacos 安全零信任实践
    作者:柳遵飞Nacos作为配置中心经常存储一些敏感信息,但是由于误用导致安全风险,最常见的主要是以下两个问题:1)Nacos暴露公网可以吗?不可以,因为Nacos定位是注册配置中心,是内部系统,不应该暴露到公网使用。2)不得已要开公网不开鉴权可以吗?不可以,开公网不开鉴权等同于裸奔,为黑客攻击......
  • Memory Layout of the C program
    reference:CompilationStepsandMemoryLayoutoftheCProgramStorageClassRAM明明断电会丢失数据,为什么初始化的全局变量存储在RAM?详细分析程序的存储TableofContentsMemoryLayoutoftheCProgramWhenyourunanyCprogram,itsexecutableimageis......