Writing to MemoryStream with StreamWriter returns

2019-04-18 09:04发布

问题:

I am not sure what I am doing wrong, have seen a lot of examples, but can't seem to get this working.

public static Stream Foo()
{
    var memStream = new MemoryStream();
    var streamWriter = new StreamWriter(memStream);

    for (int i = 0; i < 6; i++)
        streamWriter.WriteLine("TEST");

    memStream.Seek(0, SeekOrigin.Begin);
    return memStream;
}

I am doing a simple test on this method to try and get it to pass, but no matter what, my collection count is 0.

[Test]
public void TestStreamRowCount()
{
    var stream = Foo();

    using (var reader = new StreamReader(stream))
    {
        var collection = new List<string>();
        string input;

        while ((input = reader.ReadLine()) != null)
            collection.Add(input);

        Assert.AreEqual(6, collection.Count);
    }
}

Note: I changed some syntax above without compiling in the Test method. What is more important is the first method which seems to be returning an empty stream (my reader.ReadLine() always reads once). Not sure what I am doing wrong. Thank you.

回答1:

You are forgetting to flush your StreamWriter instance.

public static Stream Foo()
{
    var memStream = new MemoryStream();
    var streamWriter = new StreamWriter(memStream);

    for (int i = 0; i < 6; i++)
        streamWriter.WriteLine("TEST");

    streamWriter.Flush();                                   <-- need this
    memStream.Seek(0, SeekOrigin.Begin);
    return memStream;
}

Also note that StreamWriter is supposed to be disposed of, since it implements IDisposable, but that in turn generates another problem, it will close the underlying MemoryStream as well.

Are you sure you want to return a MemoryStream here?

I would change the code to this:

public static byte[] Foo()
{
    using (var memStream = new MemoryStream())
    using (var streamWriter = new StreamWriter(memStream))
    {
        for (int i = 0; i < 6; i++)
            streamWriter.WriteLine("TEST");

        streamWriter.Flush();
        return memStream.ToArray();
    }
}

[Test]
public void TestStreamRowCount()
{
    var bytes = Foo();

    using (var stream = new MemoryStream(bytes))
    using (var reader = new StreamReader(stream))
    {
        var collection = new List<string>();
        string input;

        while ((input = reader.ReadLine()) != null)
            collection.Add(input);

        Assert.AreEqual(6, collection.Count);
    }
}


回答2:

Since you are not using "using" or streamWriter.Flush() the writer did not commit changes to the stream. As result Stream itslef does not have data yet. In general you want to wrap manipulation with Stream and StremaWriter instances with using.

You also should consider returning new instance of MemoryStream:

using(var memStream = new MemoryStream())
{
   ....
   return new MemoryStream(memStream.ToArray(), false /*writable*/);
}


回答3:

Try flushing streamWriter after writing your lines.