2009-11-28 5 views
20

j'ai un XmlFileHelper de classe simple comme suit:c le verrouillage des fichiers # XML.load() sur les erreurs causant des disques

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 
} 

La question est que je reçois l'erreur suivante sur la charge:

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

Cela se produit lorsque cette classe est utilisée par deux instances en cours d'exécution d'un composant s'exécutant en parallèle à la fois tentant de charger le fichier xml ci-dessus, ce comportement est légitime et requis par l'application. Je veux seulement lire une fois dans le disque xml off et libérer toute référence au fichier sur le disque et utiliser une représentation en mémoire à partir de ce point.

J'aurais supposé que Load fonctionne en lecture seule et n'aurait pas besoin de verrouiller le fichier, quelle est ma meilleure façon d'obtenir le résultat souhaité et de contourner ce problème?

Merci

Répondre

20

cela dépend de ce que vous avez besoin du fichier,

Si vous avez besoin d'être threasdsafe vous devez impliment un mutex pour verrouiller le chargement Si vous n'avez pas vraiment besoin d'un chargement sécurisé (c'est-à-dire que le fichier ne change jamais), vous pouvez le charger via un flux de fichiers, puis charger le XmlDocument à partir de l'instance,

flux

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

J'essaie cela maintenant, merci – m3ntat

+0

Excellent cela a fait l'affaire! – m3ntat

-1

essayer:

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

Si le fichier est pas trop grand pour lire en mémoire à la fois:

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

Vous pouvez le faire

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

au lieu de

xmlDoc.Load(xmlFilePath);