关于写ASP的一些问题。净响应流

时间:2021-07-31 16:34:42

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:

我在用ASP做测试。NET HttpHandler用于下载直接在响应流上书写的文件,我不太清楚我是如何做到这一点的。这是一个示例方法,将来文件可以存储在数据库中的BLOB中:

        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. 当我用浏览器打开url时,会出现“保存文件”对话框……但在我点击“保存”之前,服务器似乎已经开始向流中推送数据了,这正常吗?
  3. 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?
  4. 如果我删除行"response.Flush(),当我用浏览器打开url时……我看到web服务器是如何推送数据的,但是“保存文件”对话框没有出现,(或者至少不是以合理的时间方式)为什么?
  5. 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?
  6. 当我使用WebRequest对象打开url时,我看到HttpResponse。内容长度是“-1”,尽管我可以读取流并获取文件。-1是什么意思?当HttpResponse。内容长度会显示响应的长度吗?例如,我有一个方法,它检索一个大的xml压缩,压缩后作为一个二进制流进行压缩,但是在这种情况下……当我使用WebRequest访问它时,在HttpResponse中,我可以看到内容长度和流的长度,为什么?
  7. 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.
  8. 为了在web服务器中获得最佳性能,我将字节[]数组用作缓冲区的最佳长度是多少?我读过介于4K和8K之间的东西……但是我应该考虑哪些因素才能做出正确的决定。
  9. Does this method bloat the IIS or client memory usage? or is it actually buffering the transference correctly?
  10. 这个方法会在IIS或客户端内存使用中膨胀吗?或者它实际上是在正确地缓冲移情吗?

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

抱歉,有这么多问题,我对网络开发很陌生:P

Cheers.

欢呼。

3 个解决方案

#1


17  

  1. Yes; this is normal.
  2. 是的,这是正常的。
  3. 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.
  4. 如果从不刷新,浏览器在serever完成(甚至不包括内容配置头)之前不会得到任何响应。因此,它不知道显示一个文件对话框。
  5. 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());
    
  6. I recommend 4K; I don't have any hard basis for the recommendation.
  7. 我建议4 k;我对这个建议没有任何坚实的基础。
  8. 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.
  9. 这种方法是最好的方法。通过在循环中调用Flush,您可以立即将响应发送到连线中,而不需要任何缓冲。但是,为了增加性能,可以使用GZIP压缩。

#2


2  

  1. Yes, it is buffering.
  2. 是的,它是缓冲。
  3. Flush pushes the cached content to the browser. If it is never pushed, you won't get a save dialog box.
  4. 刷新将缓存的内容推送到浏览器。如果它从未被推送,你将不会得到一个保存对话框。
  5. Hard to tell without seeing the exact files/URLs/Streams you are using.
  6. 很难分辨你正在使用的确切的文件/ url /流。
  7. I think the factors depends on how sluggish your page is, really. You will have better performance toward 4k. And perhaps, the lower value will be better to accommodate slower connections.
  8. 我认为这些因素取决于你的页面有多迟钝。你会有更好的4k表现。或许,更低的值将更好地适应较慢的连接。
  9. See #1 & 2.
  10. 看到# 1 & 2。

#3


2  

For #3 you need to set the content-length header in your http-response. Many of those values come from http headers.

对于#3,您需要在http-响应中设置内容长度标头。其中许多值来自http头。

I believe you can change the bufferring by changing a buffering property on the response object to false. Haven't done it in a while so I don't remember what it might be.

我相信您可以通过将响应对象上的缓冲属性更改为false来更改缓冲环。我有一段时间没做了,所以我不记得是什么了。

#1


17  

  1. Yes; this is normal.
  2. 是的,这是正常的。
  3. 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.
  4. 如果从不刷新,浏览器在serever完成(甚至不包括内容配置头)之前不会得到任何响应。因此,它不知道显示一个文件对话框。
  5. 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());
    
  6. I recommend 4K; I don't have any hard basis for the recommendation.
  7. 我建议4 k;我对这个建议没有任何坚实的基础。
  8. 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.
  9. 这种方法是最好的方法。通过在循环中调用Flush,您可以立即将响应发送到连线中,而不需要任何缓冲。但是,为了增加性能,可以使用GZIP压缩。

#2


2  

  1. Yes, it is buffering.
  2. 是的,它是缓冲。
  3. Flush pushes the cached content to the browser. If it is never pushed, you won't get a save dialog box.
  4. 刷新将缓存的内容推送到浏览器。如果它从未被推送,你将不会得到一个保存对话框。
  5. Hard to tell without seeing the exact files/URLs/Streams you are using.
  6. 很难分辨你正在使用的确切的文件/ url /流。
  7. I think the factors depends on how sluggish your page is, really. You will have better performance toward 4k. And perhaps, the lower value will be better to accommodate slower connections.
  8. 我认为这些因素取决于你的页面有多迟钝。你会有更好的4k表现。或许,更低的值将更好地适应较慢的连接。
  9. See #1 & 2.
  10. 看到# 1 & 2。

#3


2  

For #3 you need to set the content-length header in your http-response. Many of those values come from http headers.

对于#3,您需要在http-响应中设置内容长度标头。其中许多值来自http头。

I believe you can change the bufferring by changing a buffering property on the response object to false. Haven't done it in a while so I don't remember what it might be.

我相信您可以通过将响应对象上的缓冲属性更改为false来更改缓冲环。我有一段时间没做了,所以我不记得是什么了。