ASP 经典,下载大文件在某些​​服务器上不起作用

ASP Classic, Download big files does not work on certain servers

我有以下脚本,在本地(Windows 10 IIS,windows 2003 服务器)运行良好,但在我们的托管服务器(Windows 2003 服务器)上运行良好。超过 4mb 的任何内容都会下载非常慢,然后在到达文件末尾之前超时。但是,在本地,它下载速度快且完整。

直接下载(link 到文件本身)会在 5 秒内从我们的托管服务提供商服务器下载一个 26.5mb 的文件。因此,下载限制不存在问题。托管服务器和此脚本似乎存在问题。有什么想法吗?

Response.AddHeader "content-disposition","filename=" & strfileName
Response.ContentType = "application/x-zip-compressed" 'here your content -type

Dim strFilePath, lSize, lBlocks
Const CHUNK = 2048
set objStream = CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = 1
objStream.LoadFromfile Server.MapPath("up/"&strfileName&"") 
lSize = objStream.Size
Response.AddHeader "Content-Size", lSize
lBlocks = 1
Response.Buffer = False
Do Until objStream.EOS Or Not Response.IsClientConnected
Response.BinaryWrite(objStream.Read(CHUNK))
Loop

objStream.Close

我的代码有点不同,使用 For..Next 循环而不是 Do..Until 循环。不能 100% 确定这对您的情况是否真的有效,但值得一试。这是我的代码版本:

For i = 1 To iSz / chunkSize
    If Not Response.IsClientConnected Then Exit For
    Response.BinaryWrite objStream.Read(chunkSize)
Next 
If iSz Mod chunkSize > 0 Then 
    If Response.IsClientConnected Then 
        Response.BinaryWrite objStream.Read(iSz Mod chunkSize)
    End If 
End If

只看代码片段,它看起来不错,这正是我下载大文件时使用的方法(尤其是 Response.IsClientConnected 的使用) .

不过话虽如此,这很可能是正在读取的块的大小与文件的大小有关。

公式大致是这样的...

time to read = ((file size / chunk size) * read time) 

因此,如果我们使用您的 4 MB 文件示例 (4194304 字节) 并假设读取每个块需要 100 毫秒,则以下适用;

  • 2048 字节的块大小 (2 KB) 大约需要3 分钟阅读。

  • 20480 字节的块大小 (20 KB) 大约需要阅读时间为 20 秒。

IIS 7 及更高版本上的经典 ASP 页面默认 scriptTimeout00:01:30 因此在上面的示例中,一个 4 MB 的文件以 100 毫秒的速度连续读取 2 KB 块脚本完成前超时。

现在这些只是粗略的统计数据,您的读取时间不会一直保持不变,可能会比 100 毫秒更快(取决于磁盘读取速度),但我认为您明白了重点。

所以只需尝试增加 CHUNK

Const CHUNK = 20480 'Read in chunks of 20 KB

基本上是由于脚本超时。使用 IIS 10 升级到 Win 2016 后,我在 IIS 10 中遇到了 1GB 文件的相同问题(默认超时默认更短)。

我使用 256000 的块Server.ScriptTimeout = 600 '10 分钟