2016-08-24 3 views
1

У меня есть следующий скрипт, который работает хорошо, локально (Windows 10 IIS, Windows 2003 Server), но не на нашем сервере хостинга (Windows 2003 Server). Anything over 4mb загрузится очень медленно, а затем таймаут, прежде чем он дойдет до конца файла. Однако, локально, он загружается быстро и полно.ASP Classic, загрузка больших файлов не работает на определенных серверах

Выполнение прямой загрузки (ссылка на файл) загружает файл 26.5mb за 5 секунд с нашего сервера хостинг-провайдера. Таким образом, с лимитом загрузки нет проблем. Кажется, проблема связана с сервером хостинга и этим скриптом. Есть идеи?

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

Dim strFilePath, lSize, lBlocks 
'Const CHUNK = 2048 
' Thanks to Lankymart. I have set this and it download at 1.5MB a second, so that is running pretty well for what I need it to be. 
Const CHUNK = 2048000 
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 
+0

Возможно проблема конфигурации IIS. Я считаю, что значение по умолчанию - 4 МБ ... – sgeddes

+0

Как я уже говорил выше.Вы можете напрямую скачать файл, и он будет загружать большие файлы в кратчайшие сроки. Просто не со сценарием. –

+0

Это все код на странице или это фрагмент? Может быть, что-то другое может привести к замедлению? Или как насчет увеличения размера куска? В качестве примера скажем, что требуется 100 миллисекунд для чтения одного фрагмента * (2048 байт) *, что означает, что для загрузки 4-мегабайтного файла потребуется около 3 минут, однако увеличение размера фрагмента до 20480 * (20 КБ) * будет только ок. 20 секунд, см. Разницу? – Lankymart

ответ

3

Просто глядя на фрагменте кода он, кажется, хорошо, и это очень подход, который я хотел бы использовать для загрузки больших файлов (особенно как использование Response.IsClientConnected).

Однако, говоря, что, вероятно, размер кусков, считающихся относительно размера файла.

Очень грубо формула что-то вроде этого ...

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

Так что, если мы используем ваш пример 4 мегабайтного файла (4194304 байт) и говорят, что занимает 100 миллисекунд, чтобы прочитать каждый кусок затем применяется следующее:

  • Chunk Размер 2048 байт (2 КБ) займет ок. 3 минуты для чтения.

  • Chunk Размер 20480 байт (20 КБ) займет ок. 20 секунд для чтения.

Классический ASP страниц на IIS 7 и выше по умолчанию имеют scriptTimeout00:01:30 из так в приведенном выше примере с 4 МБ файла постоянно прочитанного на 100 миллисекунд в 2 Кбайта кусками будет таймаут перед сценарий может закончить.

Теперь это всего лишь приблизительная статистика, и ваше время чтения не будет постоянно оставаться неизменным и, скорее всего, быстрее, чем 100 миллисекунд (в зависимости от скорости чтения диска), но я думаю, вы поняли.

Так что просто попробуйте увеличить CHUNK.

Const CHUNK = 20480 'Read in chunks of 20 KB 
+0

Вы рок. Добавление 0 до конца, выполнил задание. Я только что протестировал его на сервере хостинга, и он загрузил файлы размером 26 МБ за 1/2 времени прямой загрузки, и он завершил его. Около 10 секунд для 26mb. Прямая загрузка составляет около 5 секунд. Вы думаете, что добавление другого 0 (204800) было бы в порядке, или нет? –

+0

@WayneBarron его немного проб и ошибок, лично я бы установил его в байтовых приращениях, поэтому попробовал 2 КБ, 20 КБ, поэтому в следующий раз я попробую 200 КБ * (204800 байт) *. Просто продолжайте расти, пока вы не удовлетворены пропускной способностью. Чем больше читается кусок, тем больше ресурсов требуется, поэтому это компромисс между использованием ресурсов и производительностью. – Lankymart

+0

Я установил его на 2048000. Это примерно на 1,5 Мбайт скорости загрузки. Таким образом, это должно справиться с этим довольно хорошо. Спасибо, Lankymart, хорошо. –

0

Код, который у меня есть, отличается от другого, используя цикл For..Next вместо Do..Until loop. Не 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 
+0

Я использовал «Do While» для этого типа загрузок в прошлом без проблем. – Lankymart

+1

Это личное предпочтение, но я считаю, что цикл 'Do' - это более чистый подход, а затем дополнительный бит для чтения остатка, также избегает дублирования кода в' Response.BinaryWrite() '. – Lankymart

+0

В моем случае это был размер куска, который читался, что вызывало мою проблему, как указано в принятом ответе Ланкимарта выше. –

0

В основном это связано с тайм-аутом сценария. У меня была такая же проблема с 1 ГБ файлами в IIS 10 после обновления до Win 2016 с IIS 10 (по умолчанию таймаут по умолчанию меньше).

Я использую куски 256000 и Server.ScriptTimeOut = 60 0 '10 минут

Смежные вопросы