为什么我会收到"无法访问已关闭的流"这里? [英] Why am I getting "Cannot access a closed Stream" here?

查看:1456
本文介绍了为什么我会收到"无法访问已关闭的流"这里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

堆栈跟踪看起来像


  

[的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) +13

after 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆