# Задание к занятию "Двоичные данные" ## Задача 1 Создать в справочнике Номенклатура возможность загрузки и хранения картинки. ### Описание задачи Добавить возможность загрузки и хранения картинки в справочнике Номенклатура. ### Требования к результату Конфигурация из предыдущих заданий, в которой реализована возможность загружать и просматривать из формы элемента номенклатуры. Можно выбрать каталог и картинку для загрузки. ### Процесс выполнения 1. Добавим реквизит "ПутьКартинки" с типом Хранилище значений в справочнике Номенклатура. 2. Добавим реквизит "ФайлКартинки" на форму элемента, укажем имя "ФайлКартинки" тип "Строка". 3. Добавим на событие Нажатие процедуру "ПутьКартинкиНажатие". 4. Внутри процедуры добавим выбор файла с логичными для этого фильтрами отбора формата файла. ```bsl &НаКлиенте Процедура ПутьКартинкиНажатие(Элемент, СтандартнаяОбработка) СтандартнаяОбработка = Ложь; ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие); ДиалогВыбораФайла.Фильтр = "Картинка (*.jpg)|*.jpg"; ОписаниеОповещения = Новый ОписаниеОповещения("ПутьКартинкиНажатиеПослеДиалога", ЭтотОбъект); ДиалогВыбораФайла.Показать(ОписаниеОповещения); КонецПроцедуры ``` Используем асинхронный способ. ```bsl &НаКлиенте Процедура ПутьКартинкиНажатиеПослеДиалога(ВыбранныеФайлы, ДопПараметры) Экспорт ОписаниеОповещения = Новый ОписаниеОповещения("ПутьКартинкиНажатиеПослеПомещения", ЭтотОбъект); НачатьПомещениеФайлаНаСервер(ОписаниеОповещения,,,, ВыбранныеФайлы[0], УникальныйИдентификатор) КонецПроцедуры ``` Сохраним картинку во временное хранилище. ```bsl &НаКлиенте Процедура ПутьКартинкиНажатиеПослеПомещения(ОписаниеФайла, ДопПараметры) Экспорт ПутьКартинки = ОписаниеФайла.Адрес; КонецПроцедуры ``` 5. Перед записью на сервере запишем в хранилище значений картинку. 6. При чтении на сервере получим картинку из хранилища значений. Пример получения через временное хранилище и записи в реквизит объекта через Хранилище значений. ```bsl &НаСервере Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи) ДвоичныеДанные = ПолучитьИзВременногоХранилища(ПутьКартинки); ТекущийОбъект.ФайлКартинки = Новый ХранилищеЗначения(ДвоичныеДанные); КонецПроцедуры ``` ```bsl &НаСервере Процедура ПриЧтенииНаСервере(ТекущийОбъект) ДвоичныеДанные = ТекущийОбъект.ФайлКартинки.Получить(); ПутьКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор); КонецПроцедуры ``` ## Задача 2 (со звездочкой) Разбить файл на части и склеить после этого. ### Описание задачи Изучить системные глобальные методы "РазделитьФайл" и "ОбъединитьФайлы". Реализовать аналогичную пару методов самостоятельно во внешней обработке. Внешняя обработка должна содержать 2 закладки: * Разделить файл * Объединить файлы На первой закладке расположено поле "Имя файла", в которой пользователь с помощью стандартного диалога выберет произвольный файл на диске. Так же на закладке расположено числовое поле "Размер части" и текстовое поле "Путь", в котором пользователь с помощью стандартного диалога выбора каталога выберет путь, в котором нужно разместить полученные части файла. На второй закладке должен быть размещен элемент управления ТаблицаФормы, в котором пользователь сможет указать в нужном ему порядке перечень имен файлов. Так же на закладке должен быть размещен элемент "Результат", в котором пользователь с помощью стандартного диалога сохранения укажет место, в которое нужно сохранить результат склейки. ## Порядок выполнения ### Разбиение файлов * Создать внешнюю обработку с реквизитами: "ИмяФайла", "РазмерЧасти", "Путь", "Результат" и табличной частью "ИменаЧастей" с единственным реквизитом "ИмяЧасти" * В обработке создать форму и разместить в ней 2 страницы "Разделить файл" и "Объединить файлы". На странице "Разделить файл" разместить реквизиты "Имя файла" и "Размер части". * В элементе управления "ИмяФайла" и "Путь" включить отображение кнопки выбора "КнопкаВыбора = Да"; * Реализовать алгоритм выбора файла с помощью стандартного диалога в поле "ИмяФайла" в обработчике "НачалоВыбора". * Повторить для элемента управления "Путь", но использовать диалог в режиме выбора каталога * Создать команду "РазделитьФайл" и разместить ее на форме на закладке "Разделить файл" * Написать алгоритм разбиения файла на части. Каждая часть сохраняется в отдельный файл. ### Подсказка по алгоритму разбиения * Выяснить размер исходного файла и записать в переменную "ОсталосьПрочитать". См. объект "Файл" и "ФайловыйПоток" * В цикле открыть новый файловый поток для записи. Имя части сгенерировать как `"Часть_"+"Счетчик` * Записать в файловый поток части методом `ИсходныйПоток.КопироватьВ(ПотокЧасти, РазмерЧасти)` * Перед записью проконтролировать, что `РазмерЧасти` меньше переменной `ОсталосьПрочитать`. Если РазмерЧасти больше - скопировать только оставшееся число байт * Уменьшить переменную "ОсталосьПрочитать" на "РазмерЧасти" ### Объединение файлов * На закладке "Объединение файлов" разместить табличную часть "ИменаЧастей" и поле реквизита "Результат". * В поле реквизита "Результат" включить отображение кнопки выбора и написать алгоритм выбора пути файла * Создать команду "Объединить файлы" и разместить ее на форме * Написать обработчик команды таким образом, чтобы он создал файл с именем, указанным в поле "Результат" и перенес в него содержимое всех файлов, перечисленных в таблице "ИменаЧастей" ### Подсказка по алгоритму объединения * Открыть для записи поток в файл из поля "Результат" * В цикле по таблице `ИменаЧастей` открывать потоки для чтения текущей строки таблицы и копировать их в поток-результат методом `ПотокИсточник.КопироватьВ` * Количество байт контролировать в данном случае не надо.