Xml文档被写入两次而不是通过内存中的流进行覆盖

时间:2015-04-08 20:04:10

标签: c# xml

我正在尝试在内存流中打开存档Xml文件(在zip文件中但不将其解压缩到物理目录中),然后对其进行更改并保存。但是存档xml文件不会被覆盖而是获得两个Xml数据副本。一个副本是Xml数据的原始副本,另一个副本是同一个存档文件中的Xml数据的更改/修改/编辑副本。 这是我的代码,请帮助我覆盖现有的Xml数据,而不是在同一个存档xml文件中有2个Xml数据副本。

static void Main(string[] args)
{
  string rootFolder =     @"C:\Temp\MvcApplication5\MvcApplication5\Package1";
  string archiveName = "MvcApplication5.zip";
  string folderFullPath = Path.GetFullPath(rootFolder);
  string archivePath = Path.Combine(folderFullPath, archiveName);
  string fileName = "archive.xml";

  using (ZipArchive zip = ZipFile.Open(archivePath, ZipArchiveMode.Update))
  {
      var archiveFile = zip.GetEntry(fileName);
      if (archiveFile == null)
      {
          throw new ArgumentException(fileName, "not found in Zip");
      }

      if (archiveFile != null)
      {
          using (Stream stream = archiveFile.Open())
          {
              XDocument doc = XDocument.Load(stream);
              IEnumerable<XElement> xElemAgent = doc.Descendants("application");
              foreach(var node in xElemAgent)
              {
                  if(node.Attribute("applicationPool").Value!=null)
                  {
                      node.Attribute("applicationPool").Value = "MyPool";
                  }
              }

              doc.Save(stream);
          }

          Console.WriteLine("Document saved");
      }
  }   
}

2 个答案:

答案 0 :(得分:1)

您首先从流中读取XML数据,然后写入指向文件末尾的同一个流。为了说明,假设旧文件包含ABCD,我们希望将其替换为123

当前方法将导致ABCD123,因为流指向ABCD中的最后一个字符。

如果在写入更改的文件之前将流重置为位置0(stream.Seek(0),则该文件将包含123D,因为它不会减少文件长度。

解决方法是删除旧的ZipArchiveEntry并创建一个新的。{/ p>

答案 1 :(得分:0)

I came across this same issue just now, and I fixed it by adding this first line:

                        stream.SetLength(0);
                        xmlDoc.Save(stream);

edit: I see you came across the same solution as you mentioned in the comments of the previous answer. You can add an answer to your own question. It would have helped someone like me :]