【发布时间】:2016-03-31 13:42:21
【问题描述】:
我正在尝试编辑包含在 Zip 文件中的 XmlDocument 文件:
var zip = new ZipArchive(myZipFileInMemoryStream, ZipArchiveMode.Update);
var entry = zip.GetEntry("filenameToEdit");
using (var st = entry.Open())
{
var xml = new XmlDocument();
xml.Load(st);
foreach (XmlElement el in xml.GetElementsByTagName("Relationship"))
{
if(el.HasAttribute("Target") && el.GetAttribute("Target").Contains(".dat")){
el.SetAttribute("Target", path);
}
}
xml.Save(st);
}
执行此代码后,包含的文件不会更改。如果我将 xml 写入磁盘而不是 xml.Save(st);,我得到了已编辑的。
为什么编辑后的文件没有写入 zip?我该如何解决?
编辑:
我更新了代码:
var tmp = new MemoryStream();
using (var zip = new ZipArchive(template, ZipArchiveMode.Read, true))
{
var entry = zip.GetEntry("xml");
using (var st = entry.Open())
{
var xml = new XmlDocument();
xml.Load(st);
foreach (XmlElement el in xml.GetElementsByTagName("Relationship"))
{
if (el.HasAttribute("Target") && el.GetAttribute("Target").Contains(".dat"))
{
el.SetAttribute("Target", path);
}
}
xml.Save(tmp);
}
}
using (var zip = new ZipArchive(template, ZipArchiveMode.Update, true))
{
var entry = zip.GetEntry("xml");
using (var st = entry.Open())
{
tmp.Position = 0;
tmp.CopyTo(st);
}
}
以这种方式编辑 zip 文件,但它仅在流的长度相等时才有效。如果tmp 更短,则st 的其余部分仍在文件中...
提示?
【问题讨论】:
-
我没有看到你在任何地方保存 zip :)
-
我跳过了将
myZipFileInMemoryStream保存到磁盘的部分。编辑的部分不应该包含在流中吗? -
显然,它应该 -
After retrieving the stream, you can read from or write to the stream. When you write to the stream, the modifications you make to the entry will appear in the zip archive.(MSDN)。但是您还必须回退流 -st.Position = 0,否则您只是将新 XML 添加到旧 XML 的末尾。这可能是问题吗? :) -
添加
st.Position = 0;会引发错误This operation is not supported -
嗯,ZIP 并不真正支持完整的就地更新。最好的解决方案可能只是删除文件并重新创建。
标签: c# edit xmldocument ziparchive