如何向已有的ZipArchive文件追加数据且不生成重复副本?
解决方案
首先注意:普通Dictionary<TKey, TValue>不允许添加重复键,所以你需要先将存储待写入数据的集合改为List<KeyValuePair<string, byte[]>>类型,否则执行两次Data.Add("Filename.txt", byteArray())会直接抛出重复键异常。
之后修改压缩包写入逻辑,写入前先判断压缩包内是否已存在同名文件,存在则直接在现有文件流末尾追加数据,不存在再新建文件,完整实现代码如下:
using (var memoryStream = new MemoryStream()) { using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) { // files为List<KeyValuePair<string, byte[]>>类型,支持存储重复文件名的多组数据 foreach (var file in files) { // 查找压缩包内是否已存在同名文件 var existedEntry = archive.Entries .FirstOrDefault(e => e.FullName.Equals(file.Key, StringComparison.Ordinal)); Stream entryStream; if (existedEntry != null) { // 已存在同名文件,打开流后定位到末尾准备追加 entryStream = existedEntry.Open(); entryStream.Seek(0, SeekOrigin.End); } else { // 不存在同名文件,新建文件Entry var newEntry = archive.CreateEntry(file.Key, CompressionLevel.Optimal); entryStream = newEntry.Open(); } // 写入当前字节数据 using (var writer = new BinaryWriter(entryStream)) { writer.Write(file.Value); } } } return memoryStream.ToArray(); }
注意事项
- 如果需要文件名大小写不敏感的匹配规则,可以将
StringComparison.Ordinal改为StringComparison.OrdinalIgnoreCase - 如果追加的是文本类文件,需要确保多次写入的编码格式一致,避免出现乱码
- 该实现不会生成重复的文件副本,所有同名文件对应的数据都会追加到同一个压缩文件内
内容的提问来源于stack exchange,提问作者Andrey Vasiliykov
相关产品推荐
相关产品推荐

