【问题标题】:How to deserialize xml to object without locking the file?如何在不锁定文件的情况下将 xml 反序列化为对象?
【发布时间】:2012-02-19 19:13:46
【问题描述】:

我有一个用于数据库的 xml 文件,这意味着该 xml 会经常更新。 对于 xml 数据库有一个 FileWatcher,一旦 xml 更新,我会收到一个事件,然后我将 xml 反序列化为对象并检查是否确实有更改。

我遇到的问题是,一旦我反序列化 xml,Stream Reader 就会锁定文件,所以我在尝试更新它时可能会遇到异常。

是否有可能在不锁定文件的情况下反序列化 xml?

        XmlSerializer serializer = new XmlSerializer(typeof (MyType));
        Stream reader = new FileStream(File, FileMode.Open);
        var myType = (MyType) serializer.Deserialize(reader);

【问题讨论】:

  • 用文件共享权限打开文件?
  • 这听起来效率很低。您是否考虑过使用数据库?

标签: c# xml deserialization


【解决方案1】:
new FileStream(File, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

FileShare.ReadWrite 是关键。请记住将文件流放入 using 语句中!

编辑:根据 cmets(谢谢!),如果写入文件的其他进程需要 FileShare.None,仍然存在问题。这很可能是作家的情况。如果是这种情况,唯一的解决方案是对不同的文件进行操作。我建议您在写入后的第一次访问时将文件从“file.dat”重命名为“file_readonly1.dat”。然后,您的读取进程可以根据需要多次读取文件,而不会阻止写入器。编写器将在下次运行时创建一个新文件。一旦一些读者看到新的“file.dat”,它将把它重命名为“file_readonly2.dat”。从那时起,读者应该使用该文件的较新版本。等等。我认为这个方案是 100% 安全的。

【讨论】:

  • 如果写入文件的其他进程需要 FileShare.None,这仍然可能不起作用。
  • 谢谢!我添加了一个新方案来避免这个问题。
【解决方案2】:
string xmlString = string.Empty
using (StreamReader reader = new StreamReader("xmlfile.xml"))
{
    xmlString = reader.ReadToEnd();
    // after leaving the using scope the streamreader is disposed freeing the file
}

// if the serializer needs a TextReader then you can wrap it here
StringReader strReader = new strReader(xmlString);

var xmlObject = (MyType) serializer.Deserialize(strReader)

【讨论】:

    猜你喜欢
    • 2010-09-20
    • 2015-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    相关资源
    最近更新 更多