IE2017

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

Программирование - Практика программирования

Пример использования новых возможностей платформы 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
36
.epf 1.0.0 10,40Kb 36 Скачать

См. также

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

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

Нужно еще обработок ошибок накидать для асинхронных вызовов, иначе там при ошибках кнопка передачи недоступной останется.
4. Игорь Никик (igo1) 154 05.10.16 12:53 Сейчас в теме
5. Сергей Старых (tormozit) 4338 05.10.16 17:33 Сейчас в теме
6. Сергей (Sybr) 221 06.10.16 08:46 Сейчас в теме
Делал подобное и на старых версиях платформы при помощи функции РазделитьФайл.
7. Петр Базелюк (pbazeliuk) 1291 06.10.16 09:13 Сейчас в теме
8. Алексей Белый (mrstomak) 368 06.10.16 12:24 Сейчас в теме
(6) Sybr,
РазделитьФайл, к сожалению,на веб-клиентах не поддерживается вообще.
Но принцип такой же, да.
9. Антон Иванов (BlizD) 225 06.10.16 16:46 Сейчас в теме
10. Евгений Мартыненков (JohnyDeath) 290 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) 608 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 Сейчас в теме
Кстати хорошая тема, подписался
Оставьте свое сообщение