【问题标题】:ASP.NET downloading large files of unknown sizeASP.NET 下载未知大小的大文件
【发布时间】:2019-01-09 14:16:51
【问题描述】:

我想使用ASP.NETIIS 将动态生成的文件下载到浏览器进行保存。我不知道将生成的文件的大小。

在当前表单中,我的代码生成数据并使用 HttpResponse.Write() 发送到客户端。但在最终显示保存文件对话框之前,客户端大约一分钟内没有看到任何活动。

默认情况下,IIS 缓冲要发送到客户端的输出。可以将其关闭,但这对我来说没有帮助。问题似乎是 IIS 选择格式化数据包的方式。

如果提前知道文件大小,那么我可以在标题中设置 Content-length。如果我关闭了输出缓冲,那么 IIS 可以立即开始向客户端发送数据。

但由于我不知道文件大小,IIS 似乎会缓冲输出直到达到某个限制(数据包大小或时间,我不知道),然后发送一个传输编码设置为的数据包分块。

我可以自己尝试对数据进行分块,但有没有办法让 IIS 执行分块,但使用更小的数据包大小以便更快地显示对话框?

【问题讨论】:

    标签: asp.net iis


    【解决方案1】:

    您是否尝试过偶尔调用 HttpResponse.Flush()?

    【讨论】:

      【解决方案2】:

      您是否尝试将BufferOutput 属性设置为false?另一种想法(我不知道这是否会改变任何东西)是将文件写入OutputStream 而不是调用HttpResponse.Write()

      【讨论】:

      • 是的,我将BufferOutput设置为false,并且多次使用flush。所做的只是进一步减慢速度。
      【解决方案3】:

      您怎么不知道要流式传输到浏览器的文件的大小?你的意思是 Response.BinaryWrite 吗?

      【讨论】:

      • 文件内容是从数据库中生成的。我现在正在使用 Write()。
      • 我建议在您的数据库中添加一个文件大小字段并编写一个实用程序来循环并更新它们。你犯了两个大禁忌:1) 将文件存储在数据库中 2) 流式传输文件而不先说明它有多大。
      • 谢谢,尼古拉斯。我在这个问题上一定不够清楚。我正在生成要在浏览器中作为文件下载的输出。我不存储或流式传输文件,也不知道长度是多少。
      【解决方案4】:

      尝试类似的东西:

      byte[] response_bytes = ...
      int offset = ...
      
      using (Stream writeStream = HttpContext.Response.OutputStream)
      {
          ...
          writeStream.Write(response_bytes, offset, response_bytes.Length);
      }
      

      【讨论】:

        【解决方案5】:

        到目前为止,没有可接受的答案,但我可以分享我所学到的。

        我正在使用 IIS 6 和 .NET 框架 2.0。

        似乎是 IIS 正在缓冲输出,并且不尊重我对 Flush() 的调用。事实上, Flush() 实际上减慢了下载速度。它似乎只是在 IIS 中将输出从一个进程移动到另一个进程,但效率低于不使用 Flush() 的情况。

        在测试中出现了一些有趣的行为。如果输出足够小,IIS 会将 content-length 添加到响应的标头中,然后发送。

        如果输出太大,大约 60 秒后,IIS 将 transfer-encoding: 分块添加到标头,然后添加适当的十六进制数字并发送它所拥有的内容。从那里开始,输出在我的 Flush() 调用发生时进行流式传输。

        如果我自己分块数据也没关系。 IIS 仍然缓冲输出,直到其缓冲区已满。

        也许有更好的方法在较新的框架中设置传输编码,以便 IIS 6 可以更好地处理它。

        另一种可能性是在 Metabase.xml 中尝试不同的设置。在进一步调查之前我没时间了。

        【讨论】:

          【解决方案6】:
          Response.BufferOutput = false;
          

          return File(fileStream, contentType);

          【讨论】:

          • 你应该解释你的答案。
          • bufferOuput true 将起作用,因为它以块的形式发送响应,因此客户端与服务器保持联系,因此在 buffereoutput=true 的情况下它无法关闭与服务器的连接服务器需要额外的时间来缓冲整个文件,因此会话过期,然后文件无法到达客户端
          猜你喜欢
          • 2010-12-29
          • 2019-01-20
          • 2023-03-20
          • 1970-01-01
          • 1970-01-01
          • 2012-06-06
          • 2010-10-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多