为什么我会收到"无法访问已关闭的流"这里? [英] Why am I getting "Cannot access a closed Stream" here?
问题描述
堆栈跟踪看起来像
[的ObjectDisposedException:无法访问已关闭的流。]结果
System.IO .__ Error.StreamIsClosed()+53结果
System.IO.MemoryStream.Read(字节[]缓冲区,偏移的Int32,的Int32计数)
11411219 System.Web.Mvc.FileStreamResult.WriteFile(HTT presponseBase响应)
+81 System.Web.Mvc.FileResult.ExecuteResult(ControllerContext上下文)+168结果
System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext
controllerContext,ActionResult的的ActionResult)+13
块引用>在调用后
//字节[]字节;
使用(VAR毫秒=新的MemoryStream())
{
使用(VAR DOC =新的文件())
{
使用(VAR作家= PdfWriter.GetInstance(文件,MS))
{ doc.Open();
// VAR example_html = @< P>这< EM>为< / EM><跨度类=标题的风格=文字修饰:强调;>有的< / SPAN&GT ;<强>样品< EM>文字< / EM>< / STRONG><跨度风格=颜色:红色;>!< / SPAN>< / p>中;
变种example_html = System.IO.File.ReadAllText(Path.Combine(使用Server.Mappath(〜/ EmailTemplates),template.html));
VAR example_css = @标题{字体大小:200%}。
使用(VAR srHtml =新StringReader(example_html))
{
。iTextSharp.tool.xml.XMLWorkerHelper.GetInstance()ParseXHtml(作家,DOC,srHtml);
}
使用(VAR msCss =新的MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_css)))
{
使用(VAR MSHTML =新的MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_html)))
{
iTextSharp.tool.xml.XMLWorkerHelper.GetInstance()ParseXHtml(作家,DOC,MSHTML,msCss)。
}
}
doc.Close();
}
}
//字节= ms.ToArray();
返回文件(MS,应用程序/ PDF,的test.pdf);
}我读过<一个href=\"http://stackoverflow.com/questions/10934585/memorystream-cannot-access-a-closed-stream\">MemoryStream - 无法访问一个封闭的流的,但因为我不使用是不一样的情景
的StreamReader
编辑:还没用
工作[的OutputCache(NoStore = TRUE,持续时间= 0)]
公众的ActionResult的run()
{
字节[]字节;
VAR毫秒=新的MemoryStream();
尝试
{
使用(VAR DOC =新的文件())
{
使用(VAR作家= PdfWriter.GetInstance(文件,MS))
{
writer.CloseStream = FALSE;
doc.Open();
VAR example_html = @&LT; P&gt;这&LT; EM&GT;为&lt; / EM&GT;&LT;跨度类=标题的风格=文字修饰:强调;&GT;有的&LT; / SPAN&GT;&LT ;强&GT;样品&LT; EM&GT;文字&lt; / EM&GT;&LT; / STRONG&GT;&LT;跨度风格=颜色:红色;&GT;!&LT; / SPAN&GT;&LT; / p&gt;中;
//变种example_html = System.IO.File.ReadAllText(Path.Combine(使用Server.Mappath(〜/ EmailTemplates),LinkEmailTemplate.html));
VAR example_css = @标题{字体大小:200%}。
使用(VAR msCss =新的MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_css)))
{
使用(VAR MSHTML =新的MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_html)))
{
iTextSharp.tool.xml.XMLWorkerHelper.GetInstance()ParseXHtml(作家,DOC,MSHTML,msCss)。
}
}
doc.Close();
}
}
字节= ms.ToArray();
ms.Position = 0;
返回文件(MS,应用程序/ PDF,的test.pdf);
}
抓住
{
ms.Dispose();
扔;
}
}
解决方案当你退出的操作方法,或者该流一旦关闭,而中,
使用(VAR毫秒=新的MemoryStream()) {
块。您并不需要处置的MemoryStream。通过
返回FileStreamResult目标文件(MS,应用程序/ PDF,的test.pdf);
将<一个href=\"https://github.com/aspnet/Mvc/blob/25eb50120eceb62fd24ab5404210428fcdf0c400/src/Microsoft.AspNetCore.Mvc.Core/FileStreamResult.cs#L76\"相对=nofollow>渲染后处理它。实际发送数据流的code是:受保护的异步覆盖任务WriteFileAsync(HTT presponse响应)
{
VAR的OutputStream = response.Body; 使用(的FileStream)
{
VAR bufferingFeature = response.HttpContext.Features.Get&LT; IHttpBufferingFeature&GT;();
bufferingFeature .DisableResponseBuffering()?; 等待FileStream.CopyToAsync(OutputStream中,缓冲区大小);
}
}您可以用此代替使用块:
VAR毫秒=新的MemoryStream();
尝试
{
// ..
//从伊戈尔的评论。 FileStreamResult不会重置本身流位置
ms.Position = 0;
返回文件(MS,应用程序/ PDF,的test.pdf);
}
抓住
{
ms.Dispose();
扔;
}要确保,如果发生错误流得到处理。
更新
由于伊戈尔提到了,作为源$ C $ C显示,FileStreamResult不会重置流的位置。您将有
在呼吁将其设置为0返回文件(...)
Stack trace looks like
[ObjectDisposedException: Cannot access a closed Stream.]
System.IO.__Error.StreamIsClosed() +53
System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count) +11411219 System.Web.Mvc.FileStreamResult.WriteFile(HttpResponseBase response) +81 System.Web.Mvc.FileResult.ExecuteResult(ControllerContext context) +168
System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13after invoking
//Byte[] bytes; using ( var ms = new MemoryStream() ) { using ( var doc = new Document() ) { using ( var writer = PdfWriter.GetInstance(doc, ms) ) { doc.Open(); //var example_html = @"<p>This <em>is </em><span class=""headline"" style=""text-decoration: underline;"">some</span> <strong>sample <em> text</em></strong><span style=""color: red;"">!!!</span></p>"; var example_html = System.IO.File.ReadAllText(Path.Combine(Server.MapPath("~/EmailTemplates"), "template.html")); var example_css = @".headline{font-size:200%}"; using ( var srHtml = new StringReader(example_html) ) { iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, srHtml); } using ( var msCss = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_css)) ) { using (var msHtml = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_html))) { iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msHtml, msCss); } } doc.Close(); } } //bytes = ms.ToArray(); return File(ms, "application/pdf", "Test.pdf"); }
I've read MemoryStream - Cannot access a closed Stream, but that's not the same scenario because I'm not using
StreamReader
Edit: Still not working with
[OutputCache(NoStore = true, Duration = 0)] public ActionResult Run() { Byte[] bytes; var ms = new MemoryStream(); try { using (var doc = new Document()) { using (var writer = PdfWriter.GetInstance(doc, ms)) { writer.CloseStream = false; doc.Open(); var example_html = @"<p>This <em>is </em><span class=""headline"" style=""text-decoration: underline;"">some</span> <strong>sample <em> text</em></strong><span style=""color: red;"">!!!</span></p>"; //var example_html = System.IO.File.ReadAllText(Path.Combine(Server.MapPath("~/EmailTemplates"), "LinkEmailTemplate.html")); var example_css = @".headline{font-size:200%}"; using (var msCss = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_css))) { using (var msHtml = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_html))) { iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msHtml, msCss); } } doc.Close(); } } bytes = ms.ToArray(); ms.Position = 0; return File(ms, "application/pdf", "Test.pdf"); } catch { ms.Dispose(); throw; } }
解决方案The stream was closed as soon as you exited the action method, or rather, the
using ( var ms = new MemoryStream() ) {
block.You don't need to dispose the MemoryStream. The FileStreamResult object returned by
File(ms, "application/pdf", "Test.pdf");
will dispose it after rendering. The code that actually sends the stream data is :protected async override Task WriteFileAsync(HttpResponse response) { var outputStream = response.Body; using (FileStream) { var bufferingFeature = response.HttpContext.Features.Get<IHttpBufferingFeature>(); bufferingFeature?.DisableResponseBuffering(); await FileStream.CopyToAsync(outputStream, BufferSize); } }
You can replace this using block with :
var ms = new MemoryStream(); try { //.. //From Igor's comment. FileStreamResult won't reset the stream position itself ms.Position=0; return File(ms, "application/pdf", "Test.pdf"); } catch { ms.Dispose(); throw; }
to ensure that the stream gets disposed if an error occurs.
UPDATE
As Igor mentioned, and as the source code shows, FileStreamResult won't reset the stream position. You'll have to set it to 0 before calling
return File(...)
这篇关于为什么我会收到&QUOT;无法访问已关闭的流&QUOT;这里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!