KallDrexx
KallDrexx

Reputation: 27803

Why is using a StreamWriter to write text to a string resulting in nothing being written?

I have the following code

    public void SerializeToStream(Stream stream)
    {
        var xml = // Linq to xml code here

        // Write to the stream
        var writer = new StreamWriter(stream);
        writer.Write(xml.ToString());
    }

My xml object has the correct data, and I have verified that xml.ToString() shows everything correctly, but after writer.Write(xml.ToString()) is called my incoming stream (regardless if it's a FileStream or MemoryStream still has nothing in it (and a length of zero). No exceptions are thrown. Why is this happening?

As a note, I cannot use xml.WriteTo() because the XmlWriter class adds extra stuff (the <xml> declaration tag) which I cannot have in my xml (Company policy for integration with another system I do not have control over).

Upvotes: 1

Views: 4660

Answers (3)

CD Jorgensen
CD Jorgensen

Reputation: 1391

As a general rule, any time you are using a class that implements the IDisposable interface, you should really enclose it in a using block. This ensures that the .Close() method is called before the object goes out of scope, freeing up resources. I've also noticed that without a .Flush() at the end, the contents don't always get written out.

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

using (var writer = new StreamWriter(stream))
{
    writer.Write(xml.ToString());
    writer.Flush();
    // writer.Close() can be called here, but is automatically called at the end of the using block
}

Upvotes: 1

Austin Salonen
Austin Salonen

Reputation: 50215

I would bet it's because you're not closing the StreamWriter; flushing would likely work as well.

Wrapping it in a using block will take care of both for you.

...
    using (var writer = new StreamWriter(stream))
    {
        writer.Write(xml.ToString());
    }
...

Note (from @Tigran): using: this will affect also the stream object, which may be not a good choice in the function which accepts a stream like a parameter.

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1500425

You're never flushing or closing the writer. (I'd normally suggest closing the writer, but that will also close the stream, which may not be what you want.) Simply add:

writer.Flush();

at the end of the method.

Note that you can remove the XML declaration from an XDocument, if you want. For example:

XDocument doc = new XDocument
    (new XDeclaration("1.0", "utf-8", "yes"),
     new XElement("Root", "content"));
doc.Save(Console.Out); // Includes <? xml ... ?>
doc.Declaration = null;
doc.Save(Console.Out); // No declaration...

That should make it simpler:

public void SerializeToStream(Stream stream)
{
    var xml = // Linq to xml code here
    xml.Declaration = null;
    xml.Save(stream);
}

Upvotes: 7

Related Questions