使用StreamWriter写入MemoryStream将返回空

jsm*_*ith 24 c# memorystream streamwriter

我不确定我做错了什么,看过很多例子,但似乎无法让这个工作.

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;
}
Run Code Online (Sandbox Code Playgroud)

我正在对这个方法进行一个简单的测试,试图让它通过,但无论如何,我的收集计数为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);
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:我在上面修改了一些语法而没有在Test方法中进行编译.更重要的是第一种似乎返回空流的方法(我的reader.ReadLine()总是读取一次).不确定我做错了什么.谢谢.

ang*_*son 58

您忘记刷新StreamWriter实例了.

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;
}
Run Code Online (Sandbox Code Playgroud)

还要注意,StreamWriter应该将其处理掉,因为它实现了IDisposable,但这反过来会产生另一个问题,它也将关闭底层MemoryStream.

你确定要回到MemoryStream这里吗?

我会将代码更改为:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我不同意将其转换为数组.MemoryStream可以像普通的流一样工作,并且大多数时候它的消费者并不关心它的实现.例如,很多时候在生产过程中使用MemoryStream和生成文件流 (3认同)

Ale*_*kov 12

由于您没有使用"using"或streamWriter.Flush(),因此编写器未提交对流的更改.结果Stream itslef还没有数据.通常,您希望使用Stream包装Stream和StremaWriter实例的操作.

您还应该考虑返回MemoryStream的新实例:

using(var memStream = new MemoryStream())
{
   ....
   return new MemoryStream(memStream.ToArray(), false /*writable*/);
}
Run Code Online (Sandbox Code Playgroud)

  • 为了使它只读,停止使用为可写流分配的额外内存,允许正常的流代码模式与流创建"使用".在这种特殊情况下,它并不是非常重要,但通常很高兴返回调用者可以以他们想要的方式使用的流,而不必担心如果下面的流将被关闭或更改.在这种特殊情况下,您可以使用GetBuffer而不是ToArray(它生成内部缓冲区的副本)非常有效地创建新流. (4认同)

Jef*_*dge 7

写完你的行后尝试刷新streamWriter。