【问题标题】:c# xml.Load() locking file on disk causing errorsc# xml.Load() 锁定磁盘上的文件导致错误
【发布时间】:2016-06-03 00:41:03
【问题描述】:

我有一个简单的类 XmlFileHelper 如下:

public class XmlFileHelper
{
    #region Private Members

    private XmlDocument xmlDoc = new XmlDocument();
    private string xmlFilePath;

    #endregion

    #region Constructor

    public XmlFileHelper(string xmlFilePath)
    {
        this.xmlFilePath = xmlFilePath;
        xmlDoc.Load(xmlFilePath);
    }

    #endregion

    #region Public Methods

    public XmlNode SelectSingleNode(string xPathQuery)
    {
        return xmlDoc.SelectSingleNode(xPathQuery);
    }

    public string GetAttributeValueByName(XmlNode node, string attributeName)
    {
        return node.Attributes.GetNamedItem(attributeName).Value;
    }

    #endregion

    #region Public Properties

    public string XmlFilePath
    {
        get
        {
            return xmlFilePath;
        }
    }

    #endregion
}

问题是我在加载时收到以下错误:

System.IO.IOException: The process cannot access the file ''C:\CvarUAT\ReportWriterSettings.xml'' **because it is being used by another process**

当这个类被并行运行的组件的两个运行实例用来加载上面的 xml 文件时,会发生这种情况,这是合法行为并且是应用程序所要求的。

我只想从磁盘读取 xml 一次,然后释放对磁盘上文件的任何引用,并从那时起使用内存中的表示。

我会假设 Load 以只读方式运行并且不需要锁定文件,我最好的方法是什么来达到预期的结果并解决这个问题?

谢谢

【问题讨论】:

    标签: c# xml locking load


    【解决方案1】:

    你可以这样做

    using (Stream s = File.OpenRead(xmlFilePath))
    {
        xmlDoc.Load(s);
    }
    

    而不是

    xmlDoc.Load(xmlFilePath);
    

    【讨论】:

      【解决方案2】:

      这取决于你需要从文件中得到什么,

      如果您需要它是 threasdsafe,您需要实现一个互斥锁来锁定实例之间的加载,

      如果您真的不需要线程安全加载(即文件永远不会更改),您可以通过文件流加载它,然后从流中加载 XmlDocument

                  FileStream xmlFile = new FileStream(xmlFilePath, FileMode.Open,
      FileAccess.Read, FileShare.Read);
                  xmlDoc.Load(xmlFile);
      

      【讨论】:

        【解决方案3】:

        如果文件不是太大而不能一次全部读入内存:

        xml.Load(new MemoryStream(File.ReadAllBytes(path)));
        

        【讨论】:

          【解决方案4】:

          尝试:

          xml.Load(
                 new StreamReader(
                     new FileStream(
                            path, 
                            FileMode.Open, 
                            FileAccess.Read, 
                            FileShare.Read)
                      )
                    );
          

          【讨论】:

          • 此方法不会释放创建的资源。
          猜你喜欢
          • 1970-01-01
          • 2012-08-18
          • 2020-04-01
          • 2010-11-06
          • 1970-01-01
          • 2017-08-10
          • 1970-01-01
          • 2021-10-28
          • 1970-01-01
          相关资源
          最近更新 更多