2

我目前有一个基于 .net 的学校下载站点。我们提供防病毒、autocad、spss、office 和大量大型应用程序供学生下载。当前设置为以 2 种方式中的 1 种方式处理它们;任何超过 800 megs 的内容都可以通过单独的网站直接访问,而低于 800 megs 的内容则通过使用文件流以 10,000 字节块的形式提供给用户的 .net 代码进行保护。我在以这种方式提供下载时遇到各种问题......我希望能够保护大型下载,但是 .net 站点无法处理它,并且较小的文件经常会失败。有更好的方法吗?

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

4

7 回答 7

5

如果您遇到性能问题并且您正在交付文件系统上存在的文件(相对于 DB),请使用HttpResponse.TransmitFile函数。

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

于 2009-01-12T21:35:13.263 回答
2

查看比特洪流。它是专门为这类事情设计的,而且非常灵活。

于 2009-01-12T21:17:36.590 回答
1

我有两个建议:

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

和/或

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

原因是根据微软指南

Response.IsClientConnected 有一些成本,因此仅在至少需要 500 毫秒的操作之前使用它(如果您试图维持每秒几十页的吞吐量,那将是很长的时间)。作为一般经验法则,不要在紧密循环的每次迭代中调用它

于 2009-01-12T22:02:00.433 回答
0

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

是否有一些隐藏的要求可以防止这种情况发生?

于 2009-01-12T21:43:20.173 回答
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");
    }
}
于 2009-01-12T21:43:29.270 回答
0

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

于 2009-01-12T21:45:29.623 回答
0

Amazon S3 听起来非常适合您的需求,但它是商业服务,并且文件是从他们的服务器提供的。

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

于 2009-01-12T22:36:26.353 回答