Exclusively open / modify XML file?

I need to open the XML file exclusively, make changes and save it.

I can open it and make the modification pretty easy:

DataSet ds = new DataSet();
ds.ReadXml(filename);

DataTable table = ds.Tables[0];
DataRow[] rows = table.Select("Inventory== 1");
DataRow row = rows[0];
row["Inventory"] = "2";
ds.WriteXml(filename);

Everything works fine, but it does not block the file. I need the file to be locked.

So, I tried it with a stream:

FileStream stream = File.Open(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None);

DataSet ds = new DataSet();
ds.ReadXml(stream);

DataTable table = ds.Tables[0];
DataRow[] rows = table.Select("Inventory== 1");
DataRow row = rows[0];
row["Inventory"] = "2";
ds.WriteXml(stream);
stream.Close();

This opens the file exclusively, but when it saves, it adds XML to the end of the time, it does not overwrite it, so I get something like:

<Widgets>
  <Widget Code="5" Number="10" Inventory="1" />
  <Widget Code="6" Number="11" Inventory="15" />
  <Widget Code="7" Number="12" Inventory="22" />
</Widgets>
<Widgets>
   <Widget Code="5" Number="10" Inventory="2" />
  <Widget Code="6" Number="11" Inventory="15" />
  <Widget Code="7" Number="12" Inventory="22" />
</Widgets>

I want:

<Widgets>
  <Widget Code="5" Number="10" Inventory="2" />
  <Widget Code="6" Number="11" Inventory="15" />
  <Widget Code="7" Number="12" Inventory="22" />
</Widgets>

I know that I can open a file and use the File methods to parse it and make changes ... but I was hoping for something more elegant. The first method is downloading the file using ReadXml - is the file modification really fine, but it does not have any options to open the file exclusively. Did I miss something?

+3
2

reset , , . ds.writeXml:

stream.Seek(0, SeekOrigin.Begin);
stream.SetLength(0);

, , , , .

, , , , , , , , .

+5

, reset :

using(FileStream stream = File.Open(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
    DataSet ds = new DataSet();
    ds.ReadXml(stream);

    DataTable table = ds.Tables[0];
    DataRow[] rows = table.Select("Inventory== 1");
    DataRow row = rows[0];
    row["Inventory"] = "2";

    // Reset the stream here to the beginning of the file!
    stream.Seek(0, SeekOrigin.Begin);
    ds.WriteXml(stream);
    // Reset the length of the stream prior to closing it, in case it shorter than it used to be...
    stream.SetLength(stream.Position);
}
+6

Source: https://habr.com/ru/post/1716614/


All Articles