关于ASP.NET响应流中写了一些问题 [英] Some questions about writing on ASP.NET response stream

查看:138
本文介绍了关于ASP.NET响应流中写了一些问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在做测试,ASP.NET的HttpHandler下载的文件直接在响应流书面方式,我不pretty肯定我在做它的方式。这是一个示例性方法,在未来的文件可以存储在一个BLOB在数据库中:

 公共无效的GetFile(HTT presponse响应)
    {
        字符串文件名=example.iso;
        response.ClearHeaders();
        response.ClearContent();
        response.ContentType =应用程序/八位字节流;
        response.AppendHeader(内容处置,附件;文件名=+文件名);
        使用(的FileStream FS =新的FileStream(Path.Combine(HttpContext.Current.Server.MapPath(〜/ App_Data文件),文件名),FileMode.Open))
        {
            字节[]缓冲区=新的字节[4096];
            INT32 readed = 0;            而((readed = fs.Read(缓冲液,0,buffer.Length))大于0)
            {
                response.OutputStream.Write(缓冲液,0,readed);
                response.Flush();
            }
        }
    }

不过,我不知道这是否是正确的或者有更好的方式来做到这一点。
我的问题是:


  1. 当我打开网址与浏览器,会出现保存文件对话框中...但它似乎像服务器已经开始已经将数据推到流之前,我点击保存,是正常的吗?

  2. 如果我删除行response.Flush(),当我打开网址与浏览器,...我看到了Web服务器是如何推动数据,但保存文件对话框不上来, (或者至少在一个合理的时间的方式),为什么?

  3. 当我打开URL以WebRequest对象,我看到了Htt presponse.ContentLength是-1,虽然我可以读取数据流并获取文件。什么是-1的含义是什么?当的Htt presponse.ContentLength要显示响应的长度?例如,我有一个检索XML大COM $ P $采用deflate作为二进制流psed的方法,但在这种情况下...当我用WebRequest的访问,在Htt的presponse我可以清楚地看到与流的长度,为什么?
  4. 的CONTENTLENGTH
  5. 什么是为byte []数组,我在一个Web服务器作为缓冲区使用以获得最佳性能的最佳长度是多少?我读过为4K和8K ...但我的因素要考虑,以做出正确的决定的。

  6. 请问这个方法膨胀的IIS或客户机内存使用情况?或者是它实际上正确的缓冲转移?

很抱歉这么多问题,我是pretty在Web开发新:P

干杯。


解决方案

  1. 是;这是正常的。

  2. 如果你从来没有刷新,浏览器没有得到,直到serever完成任何反应(甚至不是内容处置头)。因此,它不知道显示文件对话框。

  3. 的Content-Length 头只有在整个响应缓存被设置(如果您不冲水),或者如果你自己设置。在这种情况下,您可以并且应该自己设置;写

      response.AppendHeader(内容长度,新的FileInfo(路径).Length.ToString());


  4. 我建议4K;我没有对任何建议硬基础。

  5. 这个方法做到这一点的最好办法。通过调用刷新循环中,您发送将立即关闭线的响应,没有任何缓冲。但是,为了提高性能,可以使用GZIP COM pression。

I'm making tests with ASP.NET HttpHandler for download a file writting directly on the response stream, and I'm not pretty sure about the way I'm doing it. This is a example method, in the future the file could be stored in a BLOB in the database:

        public void GetFile(HttpResponse response)
    {
        String fileName = "example.iso";
        response.ClearHeaders();
        response.ClearContent();
        response.ContentType = "application/octet-stream";
        response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
        using (FileStream fs = new FileStream(Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data"), fileName), FileMode.Open))
        {
            Byte[] buffer = new Byte[4096];
            Int32 readed = 0;

            while ((readed = fs.Read(buffer, 0, buffer.Length)) > 0)
            {
                response.OutputStream.Write(buffer, 0, readed);
                response.Flush();
            }
        }
    }

But, I'm not sure if this is correct or there is a better way to do it. My questions are:

  1. When I open the url with the browser, appears the "Save File" dialog... but it seems like the server has started already to push data into the stream before I click "Save", is that normal?
  2. If I remove the line"response.Flush()", when I open the url with the browser, ... I see how the web server is pushing data but the "Save File" dialog doesn't come up, (or at least not in a reasonable time fashion) why?
  3. When I open the url with a WebRequest object, I see that the HttpResponse.ContentLength is "-1", although I can read the stream and get the file. What is the meaning of -1? When is HttpResponse.ContentLength going to show the length of the response? For example, I have a method that retrieves a big xml compresed with deflate as a binary stream, but in that case... when I access it with a WebRequest, in the HttpResponse I can actually see the ContentLength with the length of the stream, why?
  4. What is the optimal length for the Byte[] array that I use as buffer for optimal performance in a web server? I've read that is between 4K and 8K... but which factors should I consider to make the correct decision.
  5. Does this method bloat the IIS or client memory usage? or is it actually buffering the transference correctly?

Sorry for so many questions, I'm pretty new in web development :P

Cheers.

解决方案

  1. Yes; this is normal.
  2. If you never flush, the browser doesn't get any response until the serever finishes (Not even the Content-Disposition header). Therefore, it doesn't know to show a file dialog.
  3. The Content-Length header only gets set if the entire response is buffered (If you never flush) or if you set it yourself. In this case, you can and should set it yourself; write

    response.AppendHeader("Content-Length", new FileInfo(path).Length.ToString());
    

  4. I recommend 4K; I don't have any hard basis for the recommendation.
  5. This method is the best way to do it. By calling Flush inside the loop, you are sending the response down the wire immediately, without any buffering. However, for added performance, you can use GZIP compression.

这篇关于关于ASP.NET响应流中写了一些问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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