c # xml.Load () блокировка файла на диске, вызывающая ошибки - PullRequest
22 голосов
/ 28 ноября 2009

У меня есть простой класс 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 off, освободить любую ссылку на файл на диске и использовать представление в памяти с этого момента.

Я бы предположил, что Load работает только для чтения, и мне не нужно было бы блокировать файл. Какой мой лучший способ достичь желаемого результата и обойти эту проблему?

Спасибо

Ответы [ 4 ]

37 голосов
/ 28 ноября 2009

Вы можете сделать это

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

вместо

xmlDoc.Load(xmlFilePath);
21 голосов
/ 28 ноября 2009

это зависит от того, что вам нужно из файла,

Если вам нужно, чтобы он был безопасным, вам нужно включить мьютекс, чтобы заблокировать загрузку между экземплярами,

Если вам действительно не нужна загрузка, безопасная для потоков (т.е. файл никогда не изменяется), вы можете загрузить его через файловый поток, а затем загрузить XmlDocument из потока

            FileStream xmlFile = new FileStream(xmlFilePath, FileMode.Open,
FileAccess.Read, FileShare.Read);
            xmlDoc.Load(xmlFile);
0 голосов
/ 28 ноября 2009

Если файл не слишком большой для одновременного чтения в память:

xml.Load(new MemoryStream(File.ReadAllBytes(path)));
0 голосов
/ 28 ноября 2009

попробовать:

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