davidpcl1977
davidpcl1977

Reputation: 111

XDocument.Save() unable to access file

Hoping I might be able to get some help with an infuriating problem which I can't seem to find a definitive answer for anywhere.

I am appending data to an xml document using an XDocument object, and then overwriting the existing file using xDoc.save(path), but for some reason the first time I run the code an error is thrown even though the file is not in use by any other process.

*"The process cannot access the file "C:\XXX\XXXX\Telemetry\2011_11_22.tlm because it is being used by another process."*

Subsequent iterations do not cause a problem.

Here is my code that I am using with try/catch removed for readability:-

XElement x = GenerateTelemetryNode(h); //Create a new element to append

            if (File.Exists(path))
            {
                if (xDoc == null)
                {
                    xDoc = XDocument.Load(new StreamReader(path));
                }
            }
            else
            {
                xDoc = new XDocument();
                xDoc.Add(new XElement("TSD"));
            }
            xDoc.Element("TSD").Add(x);
            xmlPath = path;
            xDoc.Save(path);

I'm sure there's a very simple explanation for it.

Many thanks in advance for any replies.

Upvotes: 3

Views: 4369

Answers (4)

Andy Rose
Andy Rose

Reputation: 16974

I would expect the problem is the StreamReader hasn't been disposed in which case it will still be attached to the document. I would suggest using wrapping the StreamReader creation in a using clause to ensure that is disposed of immediately after the document has been loaded:

 if (xDoc == null)
 {
        using (var sr = new StreamReader(path))
        {        
           xDoc = XDocument.Load(new StreamReader(sr));
        }
 }

Upvotes: 5

Azhar Khorasany
Azhar Khorasany

Reputation: 2709

        if (File.Exists(path))
        {
            if (xDoc == null)
            {
                StreamReader stream = new StreamReader(path);
                using (stream)
                {
                    xDoc = XDocument.Load(stream);
                }
            }
        }
        else
        {
            xDoc = new XDocument();
            xDoc.Add(new XElement("TSD"));
        }
        xDoc.Element("TSD").Add(x);
        xmlPath = path;
        xDoc.Save(path);

Upvotes: 1

Polyfun
Polyfun

Reputation: 9639

Use the overload of XDocument.Load that takes a Uri (the file name) and not a stream.

Upvotes: 1

psycho
psycho

Reputation: 632

Can't test for the moment, but I'd suspect the StreamReader to be using it, especially if you first iteration only causes this Exception. Have you tried :

XElement x = GenerateTelemetryNode(h); //Create a new element to append

        if (File.Exists(path))
        {
            if (xDoc == null)
            {
                StreamReader reader = new StreamReader(path);
                xDoc = XDocument.Load(reader);
                reader.Close();
                reader.Dispose();
            }
        }
        else
        {
            xDoc = new XDocument();
            xDoc.Add(new XElement("TSD"));
        }
        xDoc.Element("TSD").Add(x);
        xmlPath = path;
        xDoc.Save(path);

Upvotes: 0

Related Questions