1

So I have the following code to convert a string to a MemoryStream https://stackoverflow.com/a/1879470/2987066

public static Stream GenerateStreamFromString(string s)
{
    var stream = new MemoryStream();
    var writer = new StreamWriter(stream);
    writer.Write(s);
    writer.Flush();
    stream.Position = 0;
    return stream;
}

Would it be correct to dispose of the StreamWriter as it implements IDisposable but as we need to return the stream we use the leaveOpen property on the StreamWriter

so would the following be correct to deal with memory leaks or is it not necessary?

public static Stream GenerateStreamFromString(string s)
{
    var stream = new MemoryStream();
    using(var writer = new StreamWriter(stream, leaveOpen: true))
    {
        writer.Write(s);
        writer.Flush();
        stream.Position = 0;
        return stream;
    }
}
JKennedy
  • 18,150
  • 17
  • 114
  • 198
  • Are you returning a string or a stream? You said string, but your code says stream. – gilliduck Feb 14 '23 at 14:42
  • sorry yea.. typo.. returning the stream – JKennedy Feb 14 '23 at 14:42
  • 1
    You don't need to dispose the StreamWriter. Per the answer you linked: _About the StreamWriter not being disposed. StreamWriter is just a wrapper around the base stream, and doesn't use any resources that need to be disposed. The Dispose method will close the underlying Stream that StreamWriter is writing to. In this case that is the MemoryStream we want to return._ – Magnetron Feb 14 '23 at 14:43
  • 1
    Perfectly reasonable question - no idea why it was downvoted... – Matthew Watson Feb 14 '23 at 14:43
  • 1
    Side note: The second most upvoted answer in the question you linked seems to be a better solution to create a stream from a string: https://stackoverflow.com/a/5238289/5762332 – Magnetron Feb 14 '23 at 14:50
  • @Magnetron I think that will give different results. The OPs code will write UTF16 chars to the stream, but the answer you linked will write UTF8 chars to it. – Matthew Watson Feb 14 '23 at 14:54
  • so am I write in thinking if I create a `new MemoryStream` (not in a using statement) thats then used by a `StreamWriter` which is used in a using statement.. Then this wouldnt be a memory leak because the streamWriter is disposing of the MemoryStream? – JKennedy Feb 14 '23 at 14:54
  • 1
    @MatthewWatson _StreamWriter defaults to using an instance of UTF8Encoding unless specified otherwise_: https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter?view=net-7.0 That confusion about the default encoding is the reason people commented the answer to always explicit pass the encoding. – Magnetron Feb 14 '23 at 15:03
  • @User1 About your last comment, by [the source code](https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs), it appears that `StreamWriter` closes the underlining `Stream` but do not call it's `Dispose`. So I would wrap the underlining `Stream` in a using block. – Magnetron Feb 14 '23 at 15:14
  • 1
    @Magnetron Thanks for the correction above. About streamwriter closing the stream but not calling Dispose(): The base [`Stream` implementation of `Dispose()`](https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs,158) just calls `Close()` so it's effectively the same thing. – Matthew Watson Feb 14 '23 at 15:30

1 Answers1

0

From the comments. StreamWriter doesnt actually hold any resources itself that need to be disposed of and therefore doesnt need to be wrapped in a using statement in the following scenario.

public static Stream GenerateStreamFromString(string s)
{
    var stream = new MemoryStream();
    var writer = new StreamWriter(stream);
    writer.Write(s);
    writer.Flush();
    stream.Position = 0;
    return stream;
}

As an aside MemoryStream does need disposing of, even if the StreamWriter is wrapped in a using statement.

The Dispose method on StreamWriter just calls Close on the underlying stream not Dispose hence why Dispose must be explicitly called on the MemoryStream

JKennedy
  • 18,150
  • 17
  • 114
  • 198