使用 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个字符?