Загрузка файлов на сервер с прогрессом и докачкой

Опубликовал Алексей Белый (mrstomak) в раздел Программирование - Практика программирования

Пример использования новых возможностей платформы 8.3.9 по низкоуровневой работе с двоичными данными для инкрементальной передачи файлов на сервер.

Приветствую, коллеги!

Хотелось бы поднять вопрос удобства загрузки больших файлов на сервер.

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

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

Ситуация, когда проект предусматривает возможность удобной загрузки файлов, а платформа ничего предоставить не может, вызывает некоторую грусть:)

Проанализировав проблему, я, в общем, увидел только 2 решения:

1. Использование JS-класса XMLHttpRequest в полеHTMLдокумента и HTTPСервиса с Post запросом (у класса XMLHttpRequestUpload есть событие onprogress). Попытка зайти с этой стороны вызывала ожесточенное сопротивление контрола IE, используемого для парсинга в полеHTMLдокумента в платформе. Проблемы решаемы, но возни тут много. Во-первых, HTML создаётся в location: about:blank, в то время как post запрос нужно слать на домен публикуемого http сервиса. Вроде как нужно использовать XDomainRequest, но он отказывается перенаправлять запрос, т.к. видит смену схемы - было непонятно что, стало http. Теоретически решаемо размещением служебной странички на IIS/Apache, из которой вызывать POST.Во-вторых, в веб-клиентах обработка JS идёт уже нативными средствами конкретного браузера - а это значит, что код нужно писать кроссбраузерный.

2. Новые объекты для работы с двоичными данными в платформе 8.3.9.

Интерес вызвали следующие классы: ЧтениеДанных,ЗаписьДанных, ФайловыйПоток, БуферДвоичныхДанных, МенеджерФайловыхПотоков.

Основная идея тут такая:

  • С помощью метода НачатьРазделениеНаЧастиПо у класса ЧтениеДанных разделить двоичные данные на равномерные куски. Можно указывать собственные размеры частей, в моём решении используются куски по 5 Мбайт. Очень важно, что использование этого метода не загружает данные в память - происходит всего-лишь разбивка больших данных на маленькие
  • Передавать данные на сервер по маленьким кусочкам
  • На сервере с помощью менеджера файловых потоков дописывать добавленные куски в файл. Для этого есть специальный метод ОткрытьДляДописывания
  • Различными решениями на форме обеспечить контроль загрузки кусков, отображать состояние, выполнять докачку только тех кусков, которые не были загружены ранее

В результате решил идти в ногу со временем и сделал вариантом №2:)

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

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

Скачать файлы

Наименование Файл Версия Размер
ЗагрузкаНаСерверСПрогрессом.epf
.epf 10,40Kb
04.10.16
35
.epf 1.0.0 10,40Kb 35 Скачать

См. также

Комментарии
1. Артур Аюханов (artbear) 850 05.10.16 10:44 Сейчас в теме
2. Василий Зайцев (vasiliy_b) 270 05.10.16 11:05 Сейчас в теме
Хорошая идея. Только контрольную сумму наверное посчитать будет не лишним. Т.к. при таком копировании файл может измениться. И бонусом возможность ставить на паузу.
3. Алексей Белый (mrstomak) 332 05.10.16 11:57 Сейчас в теме
Контрольную сумму хотел считать, увидел, что платформенные хэш-функции не поддерживаются в тонком клиенте, поэтому сделал проверку только по имени файла и количеству байт.

Ну а пауза есть..

Нужно еще обработок ошибок накидать для асинхронных вызовов, иначе там при ошибках кнопка передачи недоступной останется.
4. Игорь Никик (igo1) 127 05.10.16 12:53 Сейчас в теме
5. Сергей Старых (tormozit) 4134 05.10.16 17:33 Сейчас в теме
6. Сергей (Sybr) 218 06.10.16 08:46 Сейчас в теме
Делал подобное и на старых версиях платформы при помощи функции РазделитьФайл.
7. Петр Базелюк (pbazeliuk) 1217 06.10.16 09:13 Сейчас в теме
8. Алексей Белый (mrstomak) 332 06.10.16 12:24 Сейчас в теме
(6) Sybr,
РазделитьФайл, к сожалению,на веб-клиентах не поддерживается вообще.
Но принцип такой же, да.
9. Антон Иванов (BlizD) 132 06.10.16 16:46 Сейчас в теме
10. Евгений Мартыненков (JohnyDeath) 291 08.10.16 22:39 Сейчас в теме
Раз пошла такая пьянка - тоже подпишусь.
11. Сергей Поликарпов (Serega-artem) 10 10.10.16 18:03 Сейчас в теме
подписка, интересная тема
12. Андрей Краснокутский (Andry.Boris) 53 11.11.16 15:54 Сейчас в теме
13. Maxim Goncharov (maxx) 597 12.11.16 17:30 Сейчас в теме
14. lefthander lefthander (lefthander) 13.11.16 17:03 Сейчас в теме
Согласен, интересная тема.
15. Андрей Казанцев (ander_) 16.11.16 11:03 Сейчас в теме
16. Владимир Клименко (KliMich) 17.11.16 16:56 Сейчас в теме
Интересная тема. Попробую.
17. Денис Лопато (Terve!R) 30.11.16 10:53 Сейчас в теме
Файлообменник на 1С?)

Алексей, допилите, пожалуйста, запросник. Может получится глюки устранить?(
18. Василий Василий (VasilVtoroy) 05.12.16 13:24 Сейчас в теме
19. Биг Босс (BigBoss) 2 05.12.16 13:27 Сейчас в теме
Кстати хорошая тема, подписался