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

推荐订阅源

Y
Y Combinator Blog
IT之家
IT之家
博客园_首页
量子位
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
博客园 - 聂微东
罗磊的独立博客
酷 壳 – CoolShell
酷 壳 – CoolShell
Hugging Face - Blog
Hugging Face - Blog
V
V2EX
爱范儿
爱范儿
大猫的无限游戏
大猫的无限游戏
宝玉的分享
宝玉的分享
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
雷峰网
雷峰网
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Google DeepMind News
Google DeepMind News
Microsoft Azure Blog
Microsoft Azure Blog
有赞技术团队
有赞技术团队
S
SegmentFault 最新的问题
Engineering at Meta
Engineering at Meta
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com

博客园 - 云起

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删除后,重新创建的方式进行更新。