Xml segmentation without recycling

using (var file_stream = File.Create("users.xml")) { var serializer = new XmlSerializer(typeof(PasswordManager)); serializer.Serialize(file_stream, this); file_stream.Close(); } 

Using the above code works fine. However, when I shorten it to:

  var serializer = new XmlSerializer(typeof(PasswordManager)); serializer.Serialize(File.Create("users.xml"), this); 

I get the following exception when I try to deserialize the users.xml file in the same test: The process cannot access the users.xml file because it is being used by another process.

It seems that the reason is that the File.Create method returns an open FileStream, which I cannot close, since I am not holding it by reference.

My bad, or Microsoft ?; -)

+6
idisposable xml-serialization
source share
4 answers

The problem is that in the second example, you open a file descriptor that you never destroy, so the second time you call your method, it will throw an exception that you describe. The first fragment is preferable (you can remove the file_stream.Close () bit - it will be automatically called by Stream.Dispose ()).

+11
source share

You must serialize in the try finally block so that you can verify that the file is closed / deleted regardless of success or failure. This is a keyword using for you.

 var serializer = new XmlSerializer(typeof(PasswordManager)); var fs = File.Create("users.xml"); try { serializer.Serialize(fs,this); } finally { fs.Close(); } 
+2
source share

If you did not have a "using" statement, but the closure was saved, you would be fine.

[Edit: Added try ... finally thanks cheeso]

 var serializer = new XmlSerializer(typeof(PasswordManager)); FileStream fs; try { fs = File.Create("users.xml"); serializer.Serialize(fs, this); } finally { fs.Close(); // or fs.Dispose() } 

In this case, Dispose is preferable because it knows all the actions that it must perform to clear, including closing (and something else).

0
source share

File.Create should be placed outside the try block, as shown in my earlier answer. If you put it inside a try block, you need to check fs for the null reference before closing. The corrected code is shown below, but my first answer is much better, since you can avoid this check.

 serializer = new XmlSerializer(typeof(PasswordManager)); FileStream fs; try { fs = File.Create("users.xml"); serializer.Serialize(fs, this); } finally { if (fs != null) // in case File.Create fails fs.Close(); // or fs.Dispose() } 
0
source share

All Articles