惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
D
Docker
月光博客
月光博客
MongoDB | Blog
MongoDB | Blog
Vercel News
Vercel News
美团技术团队
博客园 - 叶小钗
I
InfoQ
Jina AI
Jina AI
博客园 - 司徒正美
雷峰网
雷峰网
B
Blog
Y
Y Combinator Blog
A
About on SuperTechFans
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
大猫的无限游戏
大猫的无限游戏
Microsoft Security Blog
Microsoft Security Blog
Stack Overflow Blog
Stack Overflow Blog
腾讯CDC
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Recent Announcements
Recent Announcements
V
V2EX
N
Netflix TechBlog - Medium

博客园 - 云起

ArcGISPro SDK Addin打包机制 一次 ArcGISPro Addin项本地化的排查实录 记一次arm机器装系统的经历 记一次vs中无法找到win sdk的问题 arcpy运行时,报错产品许可尚未初始化 Visual Studio 2022生成解决方案代码图报错“无法连接到指定的数据库” win10下定制文件夹 excel中,根据文件名查询文件路径 ArcGISPro SDK 3.1版本中使用QueuedTask的小问题 Compress-Archive压缩zip包的小瑕疵 Pro更新字段别名,重载数据后失效 在多个office文档内替换关键字 git日志分组 xlst处理时命名空间带来的小坑 使用excel生成简单的日历 微软中文输入法带来的一点小坑,导致arcgispro输入中文异常 使用C#获取文件详情 Pro更改启动界面 使用AES加密时,结果不一样 命令行程序读取注册表失败的分析 pg_index
更新压缩流
云起 · 2025-03-24 · via 博客园 - 云起

最近遇到个新需求,要对压缩包内的数据进行更新。因为数据量不大,没有采用解压后重新打包的方式,直接采用了内存流进行处理。代码如下:

void ModifyZip(string zipFilePath)
{
	byte[] zipBytes = File.ReadAllBytes(zipFilePath);
	// 读取 ZIP 文件到内存流
	using (MemoryStream zipStream = new MemoryStream(zipBytes,true))
	{
		zipStream.Write(zipBytes, 0, zipBytes.Length);
		using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Update))
		{
			//过滤要修改的文件
			var fs = archive.Entries.Where((entry) => entry.Name.EndsWith("<customFilter>")).ToArray();
			//foreach (var entry in fs)
			for (int i = 0; i < fs.Length; i++)
			{
				var entry = fs[i];
				string content;
				using (StreamReader reader = new StreamReader(entry.Open()))
				{
					content = reader.ReadToEnd();
				}

				// 重新组合内容,根据自己的业务逻辑,重新拼接内容。
				// 如果不是文本,需要根据对象组织byte数组
				string newContent = "new";

				string path = entry.FullName;
				// 替换原文件内容
				entry.Delete();
				ZipArchiveEntry newEntry = archive.CreateEntry(path);

				using (StreamWriter writer = new StreamWriter(newEntry.Open(), Encoding.UTF8))//注意数据的字符集
				{
					writer.Write(newContent);
				}
			}
		}
		File.WriteAllBytes(zipFilePath, zipStream.ToArray());
	}
}

这里有两个个小点,需要注意。

  1. 由于是要对更改压缩流的内容,免不了要更新流已有的结构和长度。所以在创建内存流的时候,不能直接使用bytes[]来构造。
    内存流在做容量计算时,只有私有成员_expandable为true时,才可以进行动态扩展,否则会报错。
    System.NotSupportedException:“Memory stream is not expandable.”
    
    _expandable默认为false,只有使用容量值初始化时,才会为true。所以采用了调用容量值构造,后进行写入bytes[]的方式,来加载流数据。
  2. 压缩流不能直接通过entry获取流然后复写。因为数据压缩后,长度及元数据都会有变化。所以采用了entry删除后,重新创建的方式进行更新。