使用 StreamWriter 写入 MemoryStream 返回空

Posted

技术标签:

【中文标题】使用 StreamWriter 写入 MemoryStream 返回空【英文标题】:Writing to MemoryStream with StreamWriter returns empty 【发布时间】:2011-08-04 21:51:12 【问题描述】:

我不确定自己做错了什么,看过很多例子,但似乎无法正常工作。

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;

我正在对这个方法做一个简单的测试,试图让它通过,但无论如何,我的收集计数是 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);
    

注意:我更改了上面的一些语法,但没有在 Test 方法中编译。更重要的是第一个方法似乎返回一个空流(我的 reader.ReadLine() 总是读取一次)。不知道我做错了什么。谢谢。

【问题讨论】:

【参考方案1】:

您忘记刷新您的 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;

还要注意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);
    

【讨论】:

我不同意将其转换为数组。 MemoryStream 可以充当普通的 ol Stream 并且大多数时候它的使用者并不关心它的实现。很多时候,您在测试时使用 MemoryStream,在生产期间使用文件流,例如 出于我的目的,我确实想返回一个 Stream。出于同样的原因,马特上面提到了。刷新 StreamWriter 是我所缺少的。谢谢。 我知道这是一篇古老的帖子。但它只是救了我。谢谢:)【参考方案2】:

由于您没有使用“使用”或 streamWriter.Flush(),因此编写器没有提交对流的更改。结果 Stream itslef 还没有数据。一般来说,您希望使用使用来包装 Stream 和 StremaWriter 实例的操作。

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

using(var memStream = new MemoryStream())

   ....
   return new MemoryStream(memStream.ToArray(), false /*writable*/);

【讨论】:

为什么要返回一个新的 MemoryStream 实例?这不是效率低下,而且是多余的吗? 使其只读,停止使用为可写流分配的额外内存,以允许在创建流时“使用”正常的流代码模式。在这种特殊情况下,它不是很重要,但通常最好返回调用者可以以他们想要的任何方式使用的流,而不必担心下面的流是否会被关闭或更改。在这种特殊情况下,您可以通过使用 GetBuffer 而不是 ToArray(复制内部缓冲区)非常有效地创建新流。【参考方案3】:

写完行后尝试刷新streamWriter。

【讨论】:

刷新流对我有帮助!只是一个旁注;我正在使用流编写器将 1348 个字节写入内存流。 1024 字节会写入(没有刷新),我花了很长时间才弄清楚,但最终刷新它移动了其他 324 字节。

以上是关于使用 StreamWriter 写入 MemoryStream 返回空的主要内容,如果未能解决你的问题,请参考以下文章

StreamWriter在Ascii值128上为每个字符写入2个字符。如何只写1个字符?

C#中StreamWriter类使用总结

Streamwriter 写入但给出网络异常

csharp C#写入文件StreamWriter

FileStream 和 StreamWriter - 如何在写入后截断文件的其余部分?

C# streamwriter方法写入汉字时乱码