处理大型下载网站的最佳方式?

时间:2009-01-12 21:15:47

标签: c# filestream

我目前在我的学校有一个基于.net的下载站点。我们提供防病毒,autocad,spss,办公室以及许多大型应用程序供学生下载的任何内容。它目前设置为以两种方式之一处理它们;任何超过800兆的东西都可以通过一个单独的网站直接访问,而800兆以下的数据是使用文件流在.net代码后面保护的,以10000字节的形式将其提供给用户。我有这种方式提供下载的各种问题......我希望能够保证大量下载,但.net网站无法处理它,而较小的文件通常会失败。有更好的方法吗?

编辑 - 我只想更新我最终如何解决这个问题:我最终将我的下载目录添加为iis中的虚拟目录并指定了自定义http处理程序。处理程序从请求中获取文件名并根据该权限检查权限,然后将用户重定向到错误/登录页面,或让下载继续。我对这个解决方案没有任何问题,我已经使用了大约7个月了,为文件提供了几个演出。

7 个答案:

答案 0 :(得分:5)

如果您遇到性能问题并且正在提供文件系统上存在的文件(而不是数据库),请使用HttpResponse.TransmitFile函数。

至于失败,你可能有一个错误。如果你发布代码,你可能会有更好的回应。

答案 1 :(得分:2)

查看比特洪流。它专为此类设计而设计,非常灵活。

答案 2 :(得分:1)

我有两条建议:

  • 增加缓冲区大小以减少迭代次数

AND / OR

  • 不要在每次迭代时调用IsClientConnected。

原因是根据Microsoft Guidelines

Response.IsClientConnected有一些成本,所以只能在至少需要500毫秒的操作之前使用它(如果你试图维持每秒数十页的吞吐量,那就很长了)。作为一般经验法则,不要在紧密循环的每次迭代中调用它

答案 3 :(得分:0)

使用强大的Web服务器(如Apache)是错误的,让它处理文件。正如您现在将较大的文件分离到网络服务器一样,为什么不以同样的方式提供较小的文件呢?

是否有一些隐藏的要求来阻止这种情况?

答案 4 :(得分:0)

好的,这就是它目前的样子......

    Stream iStream = null;

// Buffer to read 10K bytes in chunk:
byte[] buffer = new Byte[10000];

// Length of the file:
int length;

// Total bytes to read:
long dataToRead;

if (File.Exists(localfilename))
{
    try
    {
        // Open the file.
        iStream = new System.IO.FileStream(localfilename, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);

        // Total bytes to read:
        dataToRead = iStream.Length;

        context.Response.Clear();
        context.Response.Buffer = false;
        context.Response.ContentType = "application/octet-stream";
        Int64 fileLength = iStream.Length;
        context.Response.AddHeader("Content-Length", fileLength.ToString());
        context.Response.AddHeader("Content-Disposition", "attachment; filename=" + originalFilename);

        // Read the bytes.
        while (dataToRead > 0)
        {
            // Verify that the client is connected.
            if (context.Response.IsClientConnected)
            {
                // Read the data in buffer.
                length = iStream.Read(buffer, 0, 10000);

                // Write the data to the current output stream.
                context.Response.OutputStream.Write(buffer, 0, length);

                // Flush the data to the HTML output.
                context.Response.Flush();

                buffer = new Byte[10000];
                dataToRead = dataToRead - length;
            }
            else
            {
                //prevent infinite loop if user disconnects
                dataToRead = -1;
            }
        }
        iStream.Close();
        iStream.Dispose();
    }
    catch (Exception ex)
    {
        if (iStream != null)
        {
            iStream.Close();
            iStream.Dispose();
        }
        if (ex.Message.Contains("The remote host closed the connection"))
        {
            context.Server.ClearError();
            context.Trace.Warn("GetFile", "The remote host closed the connection");
        }
        else
        {
            context.Trace.Warn("IHttpHandler", "DownloadFile: - Error occurred");
            context.Trace.Warn("IHttpHandler", "DownloadFile: - Exception", ex);
        }
        context.Response.Redirect("default.aspx");
    }
}

答案 5 :(得分:0)

存在许多许可限制......例如,我们有Office 2007许可协议,该协议规定校园内的任何技术人员都可以下载和安装Office,但不能学生。所以我们不要让学生下载它。所以我们的解决方案是将这些下载隐藏在.net之后。

答案 6 :(得分:0)

Amazon S3听起来非常适合您的需求,但它是商业服务,而文件服务则来自他们的服务器。

您应该尝试联系亚马逊并要求学术定价。即使他们没有。