使用MemoryStream更新Zip文件未生效问题排查
Zip文件内文件未更新的问题排查与修复
你的代码存在两个关键问题导致修改无法保存到原Zip文件:
核心问题1:内存流修改未同步回原文件
你将原Zip文件读取到MemoryStream中进行修改,但整个流程结束后,没有把修改后的MemoryStream内容写回磁盘上的原文件。当前代码仅完成了内存中Zip数据的修改,所有操作都停留在内存里,从未持久化到原文件。
核心问题2:临时文件流位置未重置
写完temp.json后,fs2的文件指针停留在文件末尾,直接执行fs2.CopyTo(entryStream)时,会从末尾开始复制,实际没有内容写入Zip条目流,导致修改无效。
修复后的代码
public void OpenFile(string path) { // 先读取原Zip到字节数组 byte[] zipBytes; using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { using (MemoryStream stream = new MemoryStream()) { fs.CopyTo(stream); zipBytes = stream.ToArray(); } } // 在内存流中修改Zip内容 using (MemoryStream stream = new MemoryStream(zipBytes)) { using (ZipArchive zip = new ZipArchive(stream, ZipArchiveMode.Update)) { ZipArchiveEntry entry = zip.GetEntry("course/en/course.json"); if (entry == null) { // 处理条目不存在的情况 return; } using (Stream entryStream = entry.Open()) { // 读取原有内容并修改 using (StreamReader str2 = new StreamReader(entryStream)) { using (MemoryStream tempStream = new MemoryStream()) // 用内存流替代临时文件,更高效 using (StreamWriter str1 = new StreamWriter(tempStream)) { string line; while ((line = str2.ReadLine()) != null) { if (line.Contains("_partNumber")) { line = $"\"_partNumber\": \"{partNumber}\","; } str1.WriteLine(line); } // 重置临时流位置,准备写入回条目流 tempStream.Position = 0; // 清空原条目内容并写入新内容 entryStream.SetLength(0); tempStream.CopyTo(entryStream); entryStream.Flush(); } } } } // 将修改后的内存流写回原文件 using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write)) { stream.Position = 0; stream.CopyTo(fs); } } }
关键修改说明
- 拆分读写流程:先读取原Zip到字节数组,修改完成后再重新写入原文件,避免读写文件时的冲突。
- 用内存流替代临时文件:去掉磁盘临时文件,直接用
MemoryStream处理修改内容,提升效率同时避免文件IO问题。 - 重置流位置:在复制修改后的内容前,确保流的指针回到起始位置,保证完整内容被写入。
- 显式写回原文件:修改完成后,将内存流的内容写入原文件路径,完成持久化。
内容的提问来源于stack exchange,提问作者Cameron
相关产品推荐
相关产品推荐

