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 页面默认 scriptTimeout
为 00: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 分钟
我有以下脚本,在本地(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 页面默认 scriptTimeout
为 00: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 分钟