Reputation: 2606
I am dumping some log events into an XML file, every 5 minutes I start a new file. I've been using XDocument and XElement which I really like,
_xDocument = XDocument.Parse("<LogEntires/>");
_xDocument.Root.Add(xElementLogEventList.ToArray());
_xDocument.Save(_outFileName);
I'd like to persist it to disk every 10 seconds or so with a timer so the most recent events are not just in memory, and people can examine the file if necessary. But XDocument only has Save() and WriteTo() methods which write the whole document. And guess without the < /Root > tag it would be invalid Xml anyway.
My next thought is to use XmlWriter and flush my FileStream now and then, keeping track of adding the closing < /Root > tag myself... and just have invalid XML until I'm completely done and close the file.
I'd really like to have valid Xml on the disk and If I wanted to write a root tag and then five or ten seconds later when I make my next flush, just backup and remove the root tag, append the next hundred elements and write and flush the stream. xmlWriter is forward only so I'm not sure the most efficient way to do this.
What is the most efficient way to have valid xml on disk, but keep streaming new elements in at the end, and not re-write the whole document every time? My fear is that I'm missing something obvious like a xDocument.AppendUpdatesToFile(_outfile) or something obvious like that...
If not how would you efficiently find and remove the final root tag and append the new elements in a streaming manner?
Upvotes: 2
Views: 1138
Reputation: 100527
XML is not friendly to this kind of updates on disk.
Consider using collection of XML fragments (essentially omiting initial openeing tag) if you have to stick with XML.
Upvotes: 3
Reputation: 70369
A straightforward (although not very efficient) way to do this is to create the file as you do and after saving including the Tag you can "append" entries by loading it (as often as needed) and using something similar to
xmlDoc.Element("Persons").Add(new XElement("Person", new XElement("Name", txtName.Text),
new XElement("City", txtCity.Text), new XElement("Age", txtAge.Text)));
then just save it... it stay valid...
for sample code see http://www.linqhelp.com/linq-tutorials/adding-to-xml-file-using-linq-and-c/
Upvotes: 0