在ASP MVC 3中创建可下载的文本文件时无法访问关闭的流

我试图提示可下载的文本文件(.txt),但我收到此错误:

无法访问封闭的Stream。

我在这里看过类似的问题: 无法访问封闭的流但是它不是很有用。

这是我的代码:

private FileStreamResult Export() { string name = "filename.txt"; MemoryStream stream = new MemoryStream(); using (StreamWriter writer = new StreamWriter(stream)) { StringBuilder sb = new StringBuilder(); sb.Append("A text..."); writer.WriteLine(sb.ToString()); } return File(stream, "text/plain", name); } 

更新(工作副本):

这给了我一个空白的文本文件。

 private FileResult Export() { string name = "filename.txt"; MemoryStream stream = new MemoryStream(); StreamWriter writer = new StreamWriter(stream); StringBuilder sb = new StringBuilder(); sb.Append("A text..."); writer.WriteLine(sb.ToString()); writer.Flush(); stream.Seek(0, SeekOrigin.Begin); return File(stream, "text/plain", name); } 

这是正确的,当你将流包装在另一个流中时,在它们中的任何一个上调用.Close().Dispose()将处理整个流。 在这种情况下,将MemoryStream包装在StreamWriter意味着当using语句完成时, StreamWriterMemoryStream都被StreamWriter

我的猜测是,因为你正在返回一个FileStreamResult ,封装File将在不再使用流后为你关闭流。 在这种情况下,您不想使用using语句,并且希望在返回时保持流打开。

UPDATE

由于流是前向访问,因此您需要将流返回到开头以允许读取数据。

 stream.Seek(0, SeekOrigin.Begin); 

只需删除那个using语句 – 你将被处置的对象引用传递给File方法,这就是你得到exception的原因。 来自MSDN ,

调用StreamWriter.Dispose时,StreamWriter对象在提供的Stream对象上调用Dispose。

我相信File会在使用后自行配置流(未通过查看源代码validation)。

更新:

writer.Flush(); 在return语句之前应该帮助你

在FileStreamResult中使用它之前,必须将memorystream的位置设置为0,否则将从当前位置(IE结束流)读取。

 stream.Position = 0; return File(stream, "text/plain", name); 

刚刚有同样的事情。

我知道这个线程很古老,只是希望能帮助其他人解决同样的问题。

使用FileResult替换操作中的FileStreamResult类型。