4

我正在尝试在 asp.net 应用程序中实现文件下载功能。该应用程序将被大约 200 个用户同时使用来下载各种文件。它将托管在 IIS 7 上。我不希望应用程序服务器因为多个请求同时出现而崩溃。

我假设通过在循环中调用 Context.Response.Flush() ,我将刷新到那时我将读取的所有文件数据,因此应用程序内存使用将保持一致。我可以对当前代码进行哪些其他优化,或者在这样的场景中应该使用哪些其他方法?

请求将针对各种文件,文件大小可以在 100 KB 到 10 MB 之间。

我当前的代码是这样的:

FileStream inStr = null;
byte[] buffer = new byte[1024];
String fileName = @"C:\DwnldTest\test.doc";
long byteCount; inStr = File.OpenRead(fileName);

Response.AddHeader("content-disposition", "attachment;filename=test.doc");

while ((byteCount = inStr.Read(buffer, 0, buffer.Length)) > 0)
{
    if (Context.Response.IsClientConnected)
    {
        Context.Response.ContentType = "application/msword";
        //Context.Response.BufferOutput = true;                    
        Context.Response.OutputStream.Write(buffer, 0, buffer.Length);
        Context.Response.Flush();                    
    }
}
4

4 回答 4

1

您可以Response.TransmitFile在发送文件时使用它来节省服务器内存。

Response.ContentType = "application/pdf";

Response.AddHeader("content-disposition", "attachment; filename=testdoc.pdf");

Response.TransmitFile(@"e:\inet\www\docs\testdoc.pdf");

Response.End();
于 2012-10-23T14:00:28.990 回答
0

由于您将现有文件发送到客户端,请考虑使用HttpResponse.TransmitFile(http://msdn.microsoft.com/en-us/library/12s31dhy.aspx)。

查看 .NET 代码,这似乎会将文件写入 IIS,而不是在 ASP.NET 进程中读取/写入它。HttpResponse.WriteFile(string, false)并且HttpResponse.Write(string)似乎做同样的事情。

为了验证文件发送是否中继到 IIS,在HttpResponse.Output属性 - 它应该是HttpWriter. 数组现在HttpWriter._buffers应该包含一个新元素HttpFileResponseElement)。

当然,您应该始终调查缓存是否适合您的场景并测试它是否正在使用。

于 2012-10-23T14:08:03.543 回答
0

在您的代码示例中,您没有关闭/处置 inStr。这可能会影响性能。

另一种更简单的方法是使用内置方法:

写文件

它应该已经过优化,并会为您打开/关闭文件。

于 2012-10-23T13:43:16.873 回答
0

也许您想使用FileSystemWatcher类来检查文件是否被修改,并且仅在检测到此类更改时才将其读入内存。其余时间只返回已经存储在内存中的字节数组。我不知道HttpResponse.WriteFile方法是否对此类文件修改更改敏感,或者是否总是从给定路径读取文件,但这似乎也是一个不错的选择,因为它由开箱即用的框架提供服务。

于 2012-10-23T13:51:57.403 回答