gifts2017

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

Опубликовал Алексей Белый (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 31
.epf 10,40Kb
04.10.16
31
.epf 1.0.0 10,40Kb Скачать

См. также

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

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

Нужно еще обработок ошибок накидать для асинхронных вызовов, иначе там при ошибках кнопка передачи недоступной останется.
4. Игорь Никик (igo1) 05.10.16 12:53
5. Сергей Старых (tormozit) 05.10.16 17:33
6. Сергей (Sybr) 06.10.16 08:46
Делал подобное и на старых версиях платформы при помощи функции РазделитьФайл.
7. Петр Базелюк (pbazeliuk) 06.10.16 09:13
8. Алексей Белый (mrstomak) 06.10.16 12:24
(6) Sybr,
РазделитьФайл, к сожалению,на веб-клиентах не поддерживается вообще.
Но принцип такой же, да.
9. Антон Иванов (BlizD) 06.10.16 16:46
10. Евгений Мартыненков (JohnyDeath) 08.10.16 22:39
Раз пошла такая пьянка - тоже подпишусь.
11. Сергей Поликарпов (Serega-artem) 10.10.16 18:03
подписка, интересная тема
12. Андрей Краснокутский (Andry.Boris) 11.11.16 15:54
13. Maxim Goncharov (maxx) 12.11.16 17:30
14. 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С?)

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