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

Asp classic ASP经典,下载大文件在某些服务器上不起作用,asp-classic,Asp Classic,我有以下脚本,它在本地(Windows10IIS,Windows2003Server)运行良好,但在我们的托管服务器(Windows2003Server)上运行不好。任何超过4mb的文件都会下载得非常慢,然后在到达文件末尾之前超时。然而,在本地,它下载速度快且完整 直接下载(链接到文件本身)可在5秒内从托管提供商服务器下载26.5mb的文件。因此,没有下载限制的问题。托管服务器和这个脚本似乎存在一个问题。有什么想法吗 Response.AddHeader“内容处置”,“文件名=”&strfile

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

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

Response.AddHeader“内容处置”,“文件名=”&strfileName
Response.ContentType=“application/x-zip-compressed”'这里是您的内容类型
Dim strFilePath、lSize、lBlocks
常量块=2048
设置objStream=CreateObject(“ADODB.Stream”)
对象流。打开
objStream.Type=1
objStream.LoadFromfile Server.MapPath(“up/”&strfileName&“”)
lSize=objStream.Size
Response.AddHeader“内容大小”,lSize
lBlocks=1
Response.Buffer=False
直到objStream.EOS或未连接Response.IsClientConnected为止
Response.BinaryWrite(objStream.Read(CHUNK))
环
objStream,关闭

我的代码有点不同,使用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

尽管如此,很可能是读取的块的大小与文件的大小有关

非常粗略的公式是这样的

读取时间=((文件大小/块大小)*读取时间)
因此,如果我们使用您的4MB文件(4194304字节)的示例,并说读取每个块需要100毫秒,那么以下内容适用

  • 块大小为2048字节(2 KB)的数据块读取大约需要3分钟

  • 数据块大小为20480字节(20 KB),读取大约需要20秒

IIS 7和更高版本上的经典ASP页面的默认值为
00:01:30
,因此在上面的示例中,在脚本完成之前,以100毫秒的速度不断读取2 KB块中的4 MB文件将超时

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

因此,只要试着增加

Const CHUNK=20480'以20 KB的块读取

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


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

可能是IIS配置问题。我相信默认设置是4MB…正如我上面所说的。你可以直接下载这个文件,它会很快下载大文件。只是没有脚本。这是页面中的全部代码还是一个片段?可能是其他原因导致了减速?或者增加块大小呢?例如,读取一个区块(2048字节)需要100毫秒,这意味着下载一个4 MB的文件需要大约3分钟,但是将区块大小增加到20480(20 KB)只需要大约20秒,看到区别了吗?我过去对这种分块下载使用了
Do-While
,没有任何问题。这是我个人的偏好,但我发现
Do
循环是一种更干净的方法,然后有一个额外的位来读取剩余部分,也避免了
响应.BinaryWrite()
上的代码重复,正如上面Lankymart接受的答案所指出的,是读到的块大小引起了我的问题。你太棒了。将0添加到末尾,完成了该作业。我刚刚在托管服务器上测试了它,它在直接下载的1/2时间内下载了26mb的文件,并完成了下载。26mb大约10秒。直接下载大约需要5秒钟。你认为再添加一个0(204800)行吗?@WayneBarron这需要一点尝试和错误,我个人会以字节增量设置,所以尝试了2KB,20KB,接下来我会尝试200KB(204800字节)。继续增加,直到你对吞吐量满意为止。读取的块越大,需要的资源就越多,因此这是资源使用率和性能之间的折衷。我将其设置为2048000。这是拉在约1.5mb每秒下载速度。所以,这应该处理得很好。谢谢兰克马特,祝你过得愉快。非常确定。