我正在使用 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();
}
}
}
但是,我不确定这是否正确,或者是否有更好的方法。 我的问题是:
- 当我用浏览器打开 url 时,会出现“保存文件”对话框...但在我单击“保存”之前服务器似乎已经开始将数据推送到流中,这正常吗?<
- 如果我删除行“response.Flush()”,当我用浏览器打开 url 时,...我看到网络服务器如何推送数据,但“保存文件”对话框没有出现, (或者至少不是在合理的时间范围内)为什么?
- 当我打开带有 WebRequest 对象的 url 时,我看到 HttpResponse.ContentLength 为“-1”,尽管我可以读取流并获取文件。 -1是什么意思? HttpResponse.ContentLength 什么时候会显示响应的长度?例如,我有一个方法可以检索一个用 deflate 压缩的大 xml 作为二进制流,但在那种情况下......当我使用 WebRequest 访问它时,在 HttpResponse 中我实际上可以看到 ContentLength 和流的长度,为什么?
- 我用作缓冲区的 Byte[] 数组的最佳长度是多少才能在 Web 服务器中实现最佳性能?我读到过介于 4K 和 8K 之间...但我应该考虑哪些因素才能做出正确的决定。
- 此方法是否会增加 IIS 或客户端内存使用量?或者它实际上是否正确地缓冲了转移?
抱歉问了这么多问题,我是 web 开发的新手 :P
干杯。
最佳答案
- 是的;这是正常的。
- 如果您从不刷新,则浏览器在服务器完成之前不会收到任何响应(甚至
Content-Disposition
header 也不行)。因此,它不知道显示文件对话框。 Content-Length
header 只有在缓冲整个响应(如果您从不刷新)或您自己设置时才会设置。在这种情况下,您可以而且应该自己设置;写response.AppendHeader("Content-Length", new FileInfo(path).Length.ToString());
- 我推荐 4K;我没有任何确凿的建议依据。
- 这种方法是最好的方法。通过在循环内调用
Flush
,您将立即通过线路发送响应,无需任何缓冲。但是,为了提高性能,您可以使用 GZIP 压缩。
关于c# - 写在ASP.NET响应流上的一些问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2569336/