0

I have a new project that I'm working on that uses a TextWriter object to serialize a class. Something like this:

TextWriter txtStream = new StreamWriter("xmlStreamFile.xml");
xmlSel.Serialize(txtStream, gp); // gp is the class I want to serialize
txtStream.Flush();
txtStream.Close(); 

This code works the first time I use it - the file is created and the data is written ok - but the second time I try to use it I get a excception: "Cannot write to ca closed TextWriter". I just wanted to ask how can I reopen the TextWriter - or what should I do not to get this type of exception and be able to rewrite the txtStream Object. Thanks!

Alin
  • 1,044
  • 6
  • 20
  • 42
  • 2
    I'm fairly certain that the code you've included doesn't represent the code you are actually running. The exception implies that you are trying to use the StreamWriter after you've closed it. The code in your question doesn't do this. – Adam Ralph Apr 08 '12 at 08:40

3 Answers3

2

No, you cannot re-open something like a TextWriter, because in the general case it could be writing to something like a NetworkStream, or a GZipStream - and in these cases, when you close the writer (and stream) it has side-effects (terminating a network connection, writing the final gzip blocks, etc). So no: you can't do that.

Since you are writing to a file, either:

  • don't close it until you are ready
  • re-open the file (for append) when needed
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
1

The most straightforward answer would be to re-open a new TextWriter each time.

public static void SerializeAsXml(object gp, string target)
{
    XmlSerializer xmlSel = new XmlSerializer(gp.GetType());
    using (TextWriter txtStream = new StreamWriter(target))
        xmlSel.Serialize(txtStream, gp);
}

The using statement implicitly causes Flush and Close to be called on your txtStream.

Douglas
  • 53,759
  • 13
  • 140
  • 188
  • I've just tried your example - but the second time when I use this code - the program crashes at the using statement! Why is that? – Alin Apr 08 '12 at 09:27
  • Could you show us the exception you receive at the `using` statement? – Douglas Apr 08 '12 at 09:29
  • It throws the " The file **** is used by another process"! I really don't understand why! I've tried with the using statement and also manually closing the file: txtStream.Flush(); txtStream.Close(); – Alin Apr 08 '12 at 10:09
  • Do you have any other part of your code which is accessing that same file (even for reading)? If not, could you try running the application with your virus scanner turned off? – Douglas Apr 08 '12 at 11:22
0

If you want to append to the same file, just use the same TextWriter and close it when you're done:

XmlSerializer xmlSel = new XmlSerializer(typeof(Foo));
TextWriter txtStream = new StreamWriter("xmlStreamFile.xml");
for (int i = 1; i <= 3; i++)
{
    Foo foo = new Foo(i * 100);
    xmlSel.Serialize(txtStream, foo);
    Console.WriteLine("Serialize done #" + i);
    txtStream.Flush();
}
txtStream.Close();
txtStream.Dispose();

In this sample Foo is just a simple struct, but it would work with your class as well.

Edit: assuming you're using WinForms you can have the XmlSerializer and StreamWriter members of the class itself:

class Form1 : Form
{
    private XmlSerializer xmlSel = null;
    TextWriter txtStream = null;
    //....
}

Then in the button click method initialize them once if null and serialize what you need:

if (xmlSel == null)
{
    xmlSel = new XmlSerializer(typeof(Foo));
    txtStream = new StreamWriter("xmlStreamFile.xml");
}
xmlSel.Serialize(txtStream, foo);
txtStream.Flush();

And finally in the Form close event, close and dispose the writer:

txtStream.Close();
txtStream.Dispose();
Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
  • Thank you - but your example doesn't fit my program! I need to use the txtStream file everytime a user clicks a buton - not like you just said - in an iterative maner! Thank you for your help! – Alin Apr 08 '12 at 09:29
  • It still doesn't work! Even though I use the using statement / or manually closing the txtStream - I still get a "FIle is used by another process" exception! I can quite seem to understand what is the problem! – Alin Apr 08 '12 at 10:10