27

I am getting the message "Stream was not readable" on the statement:

using (StreamReader sr = new StreamReader(ms))

I have tried the tips posted here without success. Thanks for the help.

This is my code:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(Conflict));
//Serialize Conflicts array to memorystream as XML
using (MemoryStream ms = new MemoryStream())
{
    using (StreamWriter sw = new StreamWriter(ms))
    {
        foreach (Conflict ct in Conflicts)      
            xmlSerializer.Serialize(sw, ct);

        sw.Flush(); //Site tip
        ms.Position = 0;  //Site tip
    }
    //Retrieve memory stream to string
    using (StreamReader sr = new StreamReader(ms))
    {
        string conflictXml = String.Format(CultureInfo.InvariantCulture, "{0}</NewDataSet>",
Elian Ebbing
  • 18,779
  • 5
  • 48
  • 56
Arnold Krohn
  • 271
  • 1
  • 3
  • 3
  • 1
    Formatted code would be easier to follow and help debug – BrMcMullin Mar 22 '11 at 20:36
  • 2
    StreamWriter and StreamReader both close the underlying stream when disposed of, as such, when you get to trying to read from the stream that was closed when you disposed of the StreamWriter, the stream is no longer open for reading or writing. Unfortunately I am not at my computer now, but other answers on this site has classes for wrapping the underlying stream to prevent it from being closed. – Lasse V. Karlsen Mar 22 '11 at 20:37
  • A wrapper class can be found linked to from this answer of mine earlier: http://stackoverflow.com/questions/5261123/why-is-my-filestream-object-being-disposed-of-when-im-using-a-binaryreader-obj/5261202#5261202 – Lasse V. Karlsen Mar 22 '11 at 20:41

2 Answers2

33

When this block of code completes, it will also dispose the attached MemoryStream

using (StreamWriter sw = new StreamWriter(ms))
{
    foreach (Conflict ct in Conflicts)
        xmlSerializer.Serialize(sw, ct);
    sw.Flush(); //Site tip
    ms.Position = 0;  //Site tip
}

Remove the using statement, and dispose the stream manually after you are done with it

StreamWriter sw = new StreamWriter(ms);

foreach (Conflict ct in Conflicts)
    xmlSerializer.Serialize(sw, ct);
sw.Flush(); //Site tip
ms.Position = 0;  //Site tip

// other code that uses MemoryStream here...

sw.Dispose();
Joshua C
  • 117
  • 6
Charlie Brown
  • 2,817
  • 2
  • 20
  • 31
  • 2
    In .Net 4.5 there's a StreamWriter overload where can be specified to leave the stream open: https://msdn.microsoft.com/EN-US/library/gg712853(v=VS.110,d=hv.2).aspx – user3285954 Nov 03 '15 at 17:01
  • 1
    And don't forget to enclose everything in `try/finally` block and add `sw.Dispose()` in `finally` block. You will need to define `StreamWriter sw` outside `try/finally` block. – Gabrielius Feb 09 '18 at 15:49
2

Try this instead (assuming Conflicts is of type List<Conflict>):

XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Conflict>));
StringWriter sw = new StringWriter();
xmlSerializer.Serialize(sw, Conflicts);
string conflictXml = sw.GetStringBuilder().ToString();
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335