Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Upload крупных файлов  (Прочитано 23609 раз)
0 Пользователей и 3 Гостей смотрят эту тему.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« : 19-01-2007 17:09 » 

Если кто-то реализовывал загрузку крупных файлов или множества файлов через submit формы (объём request'а порядка десятков и сотен мегабайт), поделитесь опытом.

В первую очередь интересуют средства, которые позволяют обрабатывать request на стороне сервера по частям и не требуют предварительной закачки всего request'а в память.

Требования:
  • На клиенте никаких апплетов, ActiveX'ов и т.п. - чистый HTML, в нём submit форм с заполненными <input type="file"> элементами.
  • На сервере всё, что угодно.
« Последнее редактирование: 14-12-2007 14:10 от Алексей1153++ » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 19-01-2007 19:27 » 

Для клиента процесс ничем не отличается от обычной посылки методом POST.

ПО на сервере должно поддерживать длительные соединения.

С памятью напрямую это никак не связано. Если сервер делает предобработку потока данных от клиента, то он может распознать файл, посланный из формы, и сохранить его на диске. Если предобработки нет, то обрабатывающая программа получает все в исходном виде.

Из известных мне проблем - ограничения PHP: если на сервере есть (а обычно оно есть) ограничение времени выполнения скрипта и включен safe mode, то закачка больших файлов становится проблемой. Такие ограничения типичны для виртуального хостинга. Если есть контроль над сервером, то проблема решаема.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 19-01-2007 20:16 » 

Контроль над сервером полный. Выделенный корпоративный сервер. Платформа IIS + ASP.NET 2.0. Таймауты и всё прочее значения не имеет - всё настраиваемо.

Знаю, что проблема решаема. Например, на рынке есть компонент ABCUpload, вот только он стоит $900-2500 - немного, но руководство не купит. И решать вопрос придётся своими силами.

Меня интересуют известные методы решения проблемы.

Например, IIS по умолчанию получает весь request в память и только потом приступает к выполнению серверного кода. Это типовое поведение для веб-сервера?

Идея запуска некоторого серверного кода до окончания получения request - самая естественная. Какие-нибудь примеры такого (на любой платформе) у кого-нибудь есть (со среднеподробным описанием: это встроенная фича сервера или особый модуль, порядок обработки данных на сервере и т.д.)?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 19-01-2007 23:31 » 

dimka, тебя вводят в заблуждение - такая хрень не стоит ни копейки. HTTP тебе не запрещает качать файлы любых объемов - просто не предусмотрены ограничения. Все ограничения, какие есть, - все в серверном ПО - клиентское ПО проще.
Если IIS и ASP не запрещают иметь upload в нужных объемах, но какие такие доп.продукты тебе нужны?

Может, я не понял задачи или ограничений, которые ты нашел?
« Последнее редактирование: 19-01-2007 23:40 от Sel » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 20-01-2007 09:56 » 

Цитата: RXL
dimka, тебя вводят в заблуждение - такая хрень не стоит ни копейки. HTTP тебе не запрещает качать файлы любых объемов - просто не предусмотрены ограничения.
Я не о том Улыбаюсь Компоненты покупаются не ради лицензии на технологию, а ради ускорения времени разработки. Естественно, HTTP меня ничем не ограничивает. Меня пока ограничивает IIS, точнее, отсутствие знаний о нём - я не знаю, как к нему подцепиться до того, как все файлы закачаются в память (в request). Кроме того в рамках одного web-приложения IIS ставит request'ы в очередь, и пока upload не пройдёт, ничего другого (например, в другом окне браузера) в текущем приложении сделать нельзя - приходится заводить отдельное web-приложение, а у него независимая сессия и проч., и проч. В принципе, через общую БД его можно объединить - благо, я такую тему уже поднимал и решение знаю.

По задаче заказчик демонстрировал upload сотни файлов суммарным объёмом 60 Мб по модему (! есть в мире извращенцы) - процесс закачки файлов шёл часами. Пока они не закачаются все целиком, никакие серверные скрипты не выполняются - IIS их просто не вызывает.

Задача состоит в том, чтобы контролировать процесс закачки - например, показывать ProgressBar, или просто обновлять список файлов по мере их закачки на сервер. Компонент ABCUpload именно так себя и ведёт - посылает форму с файлами и затем в отдельном окошке через window.setTimeout периодически обновляет ProgressBar. Но! Он:
  • показывает реально закачанный объём и скорость закачки;
  • не грузит файлы в RAM сервера (в объект request), а непосредственно сохраняет на диск;
  • на клиенте отправка идёт submit-ом формы с <input type="file"> и окно с формой "висит" до конца загрузки файлов.
Меня более интересует, каким образом удаётся перехватить входной поток, до того (или во время того), как он начнёт сохраняться во внутренностях IIS в объект request, и, вырезая оттуда файлы, немедленно сохранять их на диск.

Компонент позиционируется как "native ASP.NET 2.0", т.е. будто бы никаких специальных надстроек над IIS не делает и написан целиком на C# .NET (также есть версия для ASP). Поставщик компонента указывает, что это у него своя собственная особая технология разработана.
« Последнее редактирование: 14-12-2007 14:11 от Алексей1153++ » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 20-01-2007 12:57 » 

dimka, а просто cgi-приложение ты не рассматриваешь? Никаких сохранений в ram - только stdin/stdout.

Реализовать параллельную выдачу статистики тоже не сложно, используя сессии.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 20-01-2007 14:48 » 

Цитата: RXL
dimka, а просто cgi-приложение ты не рассматриваешь? Никаких сохранений в ram - только stdin/stdout.
Конечно, хотелось бы остаться в рамках ASP.NET web-приложения. Но попробую.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 20-01-2007 17:10 » 

В той части, что серверный сценарий не начинает исполняться, пока файл не будет загружен в RAM, я не был не прав - доставшийся мне код мною был неправильно понят. Сценарий начинает исполняться, когда приходит заголовок запроса. Файлы же могут качаться как байтовые потоки, и происходит это только по запросу серверного скрипта.

Тем не менее, всякие запросы к web-приложению остаются в очереди на ожидание, пока серверный скрипт не примет и не обработает все файлы. Но это я уже обойду вынесением функции загрузки файлов в отдельное приложение.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 21-01-2007 17:15 » 

Реализовал демку-черновик: на каждый файл создаётся нить (thread), осуществляющая закачку; основной поток ожидает завершения дочерних и мониторит по таймеру состояние закачки, сбрасывая таблицу состояний процессов в xml-файл, который периодически читается вторым приложением. По каждому файлу известны имена исходного и целевого файлов размер, процент готовности, скорость upload'а.

Теперь вот думаю, как бы на ASP.NET 2.0 реализовать обмен данными между экземплярами веб-приложений под IIS через память, без использования БД или дисковых файлов.
« Последнее редактирование: 14-12-2007 14:12 от Алексей1153++ » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 21-01-2007 19:24 » 

Чем тебя БД не устраивает?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 21-01-2007 19:33 » 

Ну... Во-первых, БД засоряется всякой служебной информацией, к прямому назначению БД не относящиейся. Во-вторых, достаточно часто (например, раз в секунду) дёргать БД приемлемо при малой нагрузке на сервер, а при хотя бы нескольких десятках параллельно работающих приложений уже будет накладно. В-третьих, спортивный интерес - выяснить, как можно обеспечить взаимодействие процессов в .NET Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 21-01-2007 22:37 » 

Статейка в тему попалась:
http://www.codeproject.com/useritems/UpldFileToDiskProgressBar.asp
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 22-01-2007 14:42 » 

Никто случаем не знает, что нужно сделать с MS Windows 2003 Server (или IIS 6.0), чтобы включить загрузку крупных файлов (более 2 Мб) для ASP.NET?

В MS Windows XP Professional (или в IIS 5.1) достаточно в Web.Config файле приложения прописать атрибуты тэга httpRuntime: maxRequestLength и executionTimeout.

В MS Windows 2003 Server (или в IIS 6.0) этого недостаточно. Поведение весьма странное - спустя несколько секунд после отправки request'а браузером сервер возвращает пустую страницу (нормальный HTML, но без title и с пустым body). Такое происходит только при превышении request'ом размера 2 Мб, а request'ы меньшего размера нормально отрабатываются. Возвращаемая страница - не страница приложения (в приложении нет ни одного файла с пустой страницей в кодировке cp1251). Серверные скрипты не исполняются.

Полагаю, что наблюдаемое - какая-то встроенная защита сервера от DoS атак. Где и как это отключается или перенастраивается? (Подозрительных ISAPI на сервере не установлено.)
« Последнее редактирование: 14-12-2007 14:13 от Алексей1153++ » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 22-01-2007 18:17 » new

Цитата из интернета:
Цитата
FAQ : Uploading Large files under IIS6.0

Проблема:
В Windows 2003 Server существует ограничение на размер загружаемого файла, которое по умолчанию равно 200Kb, следовательно в случае попытки загрузки файла большего размера в библиотеку, или как поле статьи, Q-Publishing может выдавать ошибку.


Решение:

IIS6.0 prevent the upload of large files (+200Ko)

For IIS6.0 users, the AspMaxRequestEntityAllowed property specifies the maximum number of bytes allowed in the entity body of an ASP request. If a Content-Length header is present and specifies an amount of data greater than the value of AspMaxRequestEntityAllowed, IIS returns a 403 error response. This property is related in function to MaxRequestEntityAllowed, but is specific to ASP request. Whereas you might set the MaxRequestEntityAllowed property to 1 MB at the general World Wide Web Publishing Service (WWW Service) level, you may choose to set AspMaxRequestEntityAllowed to a lower value, if you know that your specific ASP applications handle a smaller amount of data.

Open your MetaBase.XML which is located in c:\Windows\System32\Inetsrv find the line "AspMaxRequestEntityAllowed" and change it to "1073741824".

This change does not require stopping IIS, but to make the Metabase.xml file write-able, you need to go to the IIS control panel, right click the server, select properties, and check off the box that says "allow changes to MetaBase configuration while IIS is running".

Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 22-01-2007 19:15 » 

Спасибо. Да, дело было в этом.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #15 : 23-01-2007 09:05 » 

Скромно, потупивши в землю глаза, спрошу :
Offtopic:

А как вообще происходит upload на сервер?
Какие права должны быть на каталоге?
Если можно - пример скрипта

Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 23-01-2007 09:53 » 

Sla,  аплоад происходит методом POST с content-type multipart/form-data. Есть еще метод PUT, но к формам он не применим.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 23-01-2007 11:43 » 

Цитата: Sla
Если можно - пример скрипта
В ASP.NET в методе Page_Load страницы, например, так (пишу по памяти, без отладки - возможны опечатки):
Код: (Text)
foreach(string fileKey in this.Request.Files)
{
   HttpPostedFile file = this.Request.Files[fileKey];
   FileStream output = new FileStream(file.FileName, FileMode.Create, FileAccess.Write);
   const int MaxBufferSize = 1024
   byte[] buffer = new byte[MaxBufferSize];
   int bufferSize = 0;
   do
   {
      bufferSize = file.InputStream.Read(buffer, 0, MaxBufferSize);
      if(bufferSize != 0)
      {
         output.Write(buffer, 0, bufferSize);
      }
   }
   while(bufferSize != 0);
   output.Close();
}
Правда, следует отметить, что свойство FileName может содержать полный путь - тогда его нужно будет предварительно обработать, отрезав всё начало до имени файла.

А если без управления закачкой, то можно ещё проще:
Код: (Text)
foreach(string fileKey in this.Request.Files)
{
   HttpPostedFile file = this.Request.Files[fileKey];
   file.SaveAs(file.FileName);
}
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines