128 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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