【问题标题】:LINQ to XML file not saving correctlyLINQ to XML 文件未正确保存
【发布时间】:2015-04-01 23:45:01
【问题描述】:

我有一种方法可以删除早于 10 秒的同步时间,然后在触发时添加一个新的同步时间:

    public void addSyncTime()
    {
        //delete archived sync times
        XMLDocObject.Descendants("LastSync")
           .Where(e => Convert.ToDateTime(e.Element("Time").Value) < DateTime.Now.AddSeconds(-10))
           .Where(e => e.Element("id").Value != "1")
           .Remove();
        string t1 = XMLDocObject.ToString();
        //get the last primary key added
        var lastPrimaryKey = (from i in XMLDocObject.Element("DataLoadTimes").Elements("LastSync").Elements("id")
                              select i).LastOrDefault().Value;
        //increment it once
        int newPrimaryKey = Convert.ToInt32(lastPrimaryKey) + 1;
        //create element to insert
        var newElement = new XElement("LastSync",
               new XElement("id", newPrimaryKey),
               new XElement("Time", DateTime.Now.ToString()));
        //add to XML doc object
        XMLDocObject.Element("DataLoadTimes").Add(newElement);
        string t2 = XMLDocObject.ToString();
    }

以上字符串用于断点测试。

上面的代码创建这样的 XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!--QTabs Data Storage-->
<DataLoadTimes>
  <LastSync>
    <id>1</id>
    <Time>4/1/2015 10:29:13 AM</Time>
  </LastSync>
  <LastSync>
    <id>2</id>
    <Time>4/1/2015 10:29:14 AM</Time>
  </LastSync>
  <LastSync>
    <id>3</id>
    <Time>4/1/2015 10:29:15 AM</Time>
  </LastSync>
</DataLoadTimes>

这是触发上述内容后保存到 XML 的保存方法:

    public async void saveToXmlFile()
    {
        //storageFile = await storageFolder.GetFileAsync(Settings.xmlFile);
        using (Stream fileStream = await storageFile.OpenStreamForWriteAsync())
        {
            XMLDocObject.Save(fileStream);
        }
    }

现在,当多次使用第一种方法并保存时,我得到一个损坏的 XML 文件:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!--QTabs Data Storage-->
<DataLoadTimes>
  <LastSync>
    <id>1</id>
    <Time>4/1/2015 10:23:53 AM</Time>
  </LastSync>
  <LastSync>
    <id>2</id>
    <Time>4/1/2015 10:27:04 AM</Time>
  </LastSync>
</DataLoadTimes>  <id>3</id>
    <Time>4/1/2015 10:26:43 AM</Time>
  </LastSync>
  <LastSync>
    <id>4</id>
    <Time>4/1/2015 10:26:44 AM</Time>
  </LastSync>
</DataLoadTimes>

注意这一行:&lt;/DataLoadTimes&gt; &lt;id&gt;3&lt;/id&gt;

那么这里发生了什么?调试显示存储在XDocument对象中的试图保存的字符串是正确的:

"<!--QTabs Data Storage-->\r\n<DataLoadTimes>\r\n  <LastSync>\r\n    <id>1</id>\r\n    <Time>4/1/2015 10:23:53 AM</Time>\r\n  </LastSync>\r\n  <LastSync>\r\n    <id>2</id>\r\n    <Time>4/1/2015 10:27:04 AM</Time>\r\n  </LastSync>\r\n</DataLoadTimes>"

为什么文件乱了?

【问题讨论】:

  • 要保存的文件在写入之前不会被截断,因此您只是覆盖了第一部分,其余部分是之前的内容。您需要向我们展示 storageFile.OpenStreamForWriteAsync() 的实际作用。
  • @Charles Mager 如何截断文件? storageFile 来自 Windows.Storage;这就是我的初始化方式: StorageFile storageFile = await storageFolder.GetFileAsync("myxmlfile.xml");

标签: c# xml linq linq-to-xml


【解决方案1】:

我对 WinRT 不太熟悉,但从文档中我认为您需要使用:

await storageFolder.CreateFileAsync("myxmlfile.xml", CreationCollisionOption.ReplaceExisting);

GetFileAsync 将按原样打开现有文件 - 这将允许您读取它的内容。由于您正在编写的内容小于现有内容,因此不会触及剩余的现有内容。

如果您想坚持使用GetFileAsync,那么在编写之前设置fileStream.Length = 0 应该可以解决您遇到的问题。

【讨论】:

    猜你喜欢
    • 2010-11-01
    • 1970-01-01
    • 2020-07-29
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    相关资源
    最近更新 更多