Михаил Сайко
Двоичные данные платформы 1С:Предприятие – это универсальный объект встроенного языка программирования для работы с файлами. Благодаря объекту ДвоичныеДанные можно любой файл представить в виде последовательности байт. Объект доступен в тонком клиенте, веб-клиенте, мобильном клиенте, на сервере, толстом клиенте, внешнем соединении, мобильном приложении (клиент/сервер).
Объект сериализуется
Данный объект может быть сериализован в/из XML, может использоваться в реквизитах управляемой формы, а также он может быть сериализован в/из XDTO. Тип XDTO, соответствующий данному объекту, определяется в пространстве имен . Имя типа XDTO может быть любым из перечисленных: base64Binary, hexBinary.
Благодаря тому, что двоичные данные доступны и на клиенте, и на сервере, мы можем смело передавать файл в виде двоичных данных с клиента на сервер, однако рекомендованный «шаблон» для передачи файла – использовать хранилище значений.
Задачи, для решения которых можно использовать двоичные данные:
- Хранение файлов в базе данных (с использованием ХранилищеЗначения);
- Передача файла с клиента на сервер;
- Передача файлов при работе с протоколом HTTP;
- Передача вложений при работе с электронными письмами;
- Криптография;
- Представления файла в виде текста (с использованием Base64).
Работа с двоичными данными:
Данный пример кода показывает, как прочитать двоичные данные и передать их с клиента на сервер, используя объект ДвоичныеДанные.
Примеры по работе с двоичными данными
Самый очевидный пример, где применяются двоичные данные, – сохранение файла в базе данных. Для хранения файла в виде двоичных данных необходимо в объекте добавить реквизит с типом «ХранилищеЗначений». Далее представлен пример кода по работе с реквизитом (заполнение значения и получение значения).
Заполнение:
Получение (фрагмент кода, выполняемый на сервере):
Рассмотрим еще один пример: скачивание картинки из интернета и отображение ее на управляемой форме. Для этого также добавляем реквизит с типом ХранилищеЗначения, в котором будет помещаться картинка в двоичном формате.
Функция, скачивающая картинку из интернета:
Использование функции:
Теперь у нас в реквизите «Аватар» лежат двоичные данные картинки. Чтобы картинку вывести на управляемую форму, необходимо добавить реквизит формы «Тип строка», перекинуть его на форму (drag-and-drop), либо создать самостоятельно элемент формы, указав в поле «Путь к данным» наш реквизит «Картинка», после чего изменить вид на «Поле картинки».
По событию ПриСозданииНаСервере
Готово, на форме у нас картинка.
Двоичные данные и потоки
Говоря о двоичных данных, стоит упомянуть о возможности работы с потоками. Она появилась относительно недавно, а именно в версии 8.3.9. Чтобы потоком можно было читать из двоичных данных, применяется метод ОткрытьПотокДляЧтения. Допустим, у нас в базе данных лежит заархивированный xml-файл (как хранить файлы в базе данных рассматривалось ранее). Нам нужно вывести пользователю содержимое этого файла, или у вас настроен какой-то обмен, и вы передаете файлы в заархивированном виде (для экономии трафика).
Последовательность действий при работе с двоичными данными без использования потоков:
- Получить двоичные данные из базы;
- Записать их во временный файл;
- Разархивировать;
- Удалить временный файл;
- Прочитать разархивированный файл.
Последовательность действий при работе с потоками:
- Получить двоичные данные из базы;
- Открыть поток для чтения;
- Разархивировать;
- Прочитать разархивированный файл.
Пример кода без использования потоков:
Пример кода по работе с потоком:
Если диск у вас на SSD, рекомендую использовать потоки не только в примере с архивацией, а везде, где это возможно. Да, в данном примере все же происходит запись на диск (разархивация), но будем надеяться, когда-нибудь 1С реализует метод двоичных данных ОткрытьПотокДляЗаписи.
Работа с Base64
Base64 – это стандарт, позволяющий кодировать двоичные данные в виде строки (для кодирования используется 64 символа таблицы ASCII, отсюда и название). Тип ДвоичныеДанные сериализуем, то есть его можно представить в виде XML, для этого применяется объект встроенного языка СериализаторXDTO. После сериализации данные представлены одним узлом base64Binary, содержимое которого есть последовательность байт, закодированная в формате Base64.
строка в Base64
Платформа 1С также позволяет кодировать двоичные данные, не прибегая к сериализации. Для этого есть две функции:
Они преобразуются в Base64 и обратно в двоичные данные.
Если у вас остались вопросы по работе с двоичными данными в среде 1С:Предприятие, обратитесь к нашим специалистам и получите консультацию по 1С 8.3 или воспользуйтесь услугами по сопровождению 1С.
Реализовано в версии 8.3.10.2168.
Мы постепенно наращиваем функциональность работы с двоичными данными. Для этого есть несколько причин. Во-первых, на первом этапе мы реализовали не всё из того, что было нами задумано. А во-вторых, в процессе обсуждения новых возможностей, мы получили от вас ряд пожеланий, которые мы также решили реализовать.
Новые функции для преобразования двоичных данных в разные форматы
В глобальный контекст мы добавили большое количество новых функций для преобразования двоичных данных. Так, например, вы можете выполнять прямое и обратное преобразование двоичных данных в обычную строку, строку формата Base64 и строку формата BinHex. Кроме этого сами двоичные данные вы можете преобразовать в форматы Base64, BinHex и обратно.
Аналогичные преобразования поддерживаются и для типа БуферДвоичныхДанных. Кроме этого буфер двоичных данных вы можете преобразовывать в двоичные данные и обратно.
Помимо этого две новые функции позволяют разделить двоичные данные на несколько частей, и наоборот, объединить несколько объектов типа ДвоичныеДанные в один. При этом новый объект будет содержать данные всех частей в том порядке, который вы укажете.
Эти функции по своему смыслу аналогичны разделению и объединению файлов, но во многих случаях они более эффективны. Потому что не нужно предварительно сохранять двоичные данные в файл, и потому, что при разделении отсутствует лишнее копирование данных.
Добавление возможности работы с потоками тем объектам, которые работают с файлами
Поскольку использование двоичных данных во многом связано с файловыми операциями, мы посчитали совершенно логичным и естественным добавить работу с потоками в те объекты, которые сейчас тем или иным образом читают и пишут файлы.
В результате теперь вы можете открывать потоки для чтения и записи при использовании таких объектов как:
- ЧтениеТекста и ЗаписьТекста;
- ЧтениеFastInfoSet и ЗаписьFastInfoSet;
- ЧтениеHtml и ЗаписьHtml;
- ЧтениеJSON и ЗаписьJSON;
- ЧтениеXML и ЗаписьXML;
- ЧтениеZipФайла и ЗаписьZipФайла.
Вы можете получать тело как поток, когда работаете с HTTP:
- HTTPЗапрос и HTTPОтвет;
- HTTPСервисЗапрос и HTTPСервисОтвет.
Вы можете записывать в поток и читать из потока при работе с объектами:
- ТекстовыйДокумент;
- ТабличныйДокумент;
- ФорматированныйДокумент;
- ГеографическаяСхема;
- ГрафическаяСхема;
- FTPСоединение.
Запись в поток доступна теперь при работе с типами Картинка и ПреобразованиеККаноническомуXML. А кроме этого работа с потоками поддерживается теперь в различных методах, которые есть у типов ПреобразованиеXSL, МенеджерКриптографии, СертификатКриптографии и ХешированиеДанных.
Эффективное копирование с помощью чтения и записи данных
Инструменты для работы с двоичными данными, которые мы реализовали на первом этапе, позволяли копировать потоки. Но на больших объёмах данных эта операция выполнялась не очень эффективно.
Поэтому у типа ЧтениеДанных мы реализовали новый метод КопироватьВ(). Он не только устраняет эту проблему, но и упрощает текст, делая его более понятным.
Например, раньше можно было получить двоичные данные из одного потока, и записать их в другой поток.
Теперь нет необходимости получать двоичные данные, копирование выполняется ещё на этапе чтения данных.
Приятным моментом является то, что копировать можно не только в поток, но и в объект ЗаписьДанных. Этот вариант удобен тогда, когда, помимо данных из исходного потока, вам требуется записать в выходной поток какие-то свои данные.
Побитовые логические операции с буфером двоичных данных
Теперь вы можете использовать побитовые логические операции при работе с буферами двоичных данных. В результате этих операций в исходный буфер будет записан результат побитового объединения исходных байтов и байтов в заданном буфере по правилам выбранной логической операции. Мы реализовали следующие операции:
- ЗаписатьПобитовоеИ();
- ЗаписатьПобитовоеИли();
- ЗаписатьПобитовоеИсключительноеИли();
- ЗаписатьПобитовоеИНе();
- Инвертировать().
Хорошим примером использования побитовых логических операций является задача декодирования формата обмена с торговым оборудованием. Например, формат обмена с торговым оборудованием описывается полем длиной в 1 байт. Это поле содержит набор признаков, описывающих номенклатуру товара:
- Биты 0-2: налоговая ставка;
- Бит 3: 0 — штучный товар, 1 — весовой товар;
- Бит 4: 0 — разрешить продажу, 1 — запретить продажу;
- Бит 5: 0 — разрешить подсчет количества, 1 — запретить подсчет количества;
- Бит 6: 0 — одиночная продажа запрещена, 1 — одиночная продажа разрешена;
- Бит 7: зарезервировано.
Тогда код, извлекающий эту информацию, и представляющий её в виде, удобном для дальнейшей обработки, может выглядеть так.
Получение числа из шестнадцатеричных и двоичных литералов
Мы добавили две новые функции глобального контекста, которые преобразуют шестнадцатеричные и двоичные литералы в числа:
- ЧислоИзШестнадцатеричнойСтроки();
- ЧислоИзДвоичнойСтроки().
Двоичные литералы удобно использовать для определения масок при совместном использовании с побитовыми операциями. Например, в предыдущем примере с разбором формата обмена с торговым оборудованием, маски задаются с использованием десятичных чисел. Это не очень удобно, так как при написании и чтении кода нужно постоянно производить мысленную трансляцию десятичного числа в двоичную систему.
Вместо этого гораздо удобнее использовать двоичные литералы. При этом код становится более наглядным и вероятность ошибки значительно уменьшается.
Шестнадцатеричные литералы удобно использовать при разборе технических форматов: форматы изображений, звука, видео.
Изменения в технологии внешних компонент NativeAPI
Раньше при передаче двоичных данных между 1С:Предприятием и внешней компонентой существовал ряд ограничений. Например, передать двоичные данные во внешнюю компоненту было нельзя, а при работе в веб-клиенте обмен двоичными данными был вообще невозможен.
Теперь мы убираем все эти ограничения. Обмен двоичными данными вы можете осуществлять в обе стороны и даже в веб-клиенте.
На работе существующих внешних компонент это никак не отразится. Они будут работать, как и раньше. А вот во вновь создаваемых компонентах вы сможете теперь в качестве параметров передавать объекты ДвоичныеДанные.
Важное замечание в начале. Основной режим работы 1С в этой статье предполагается 1С 8.3.7 в режиме тонкого клиента без модальных вызовов — самый современный на настоящий момент, на который вскоре должны быть переведены все конфигурации. Также постараюсь описать особенности работы в Веб-Клиенте.
Что такое двоичные данные и как с ними можно работать в 1С 8
Двоичные данные (или бинарные) — это файл данных произвольного формата.
Платформа 1С (8.3 и 8.2) в общем случае понятия не имеет, что это. Предполагается, что программист или пользователь знает, какие именно это данные и как их применять. Тем не менее, если в двоичные данные загружен графический файл, формат которого понимает объект типа «Картинка», то при инициализации картинки такими двоичными данными картинка будет нормально показана, а её свойство «Формат» примет правильное значение.
Платформа 1С при работе с двоичными данными может:
- Хранить в базе данных в реквизитах типа «ХранилищеЗначения», в справочниках, документах, регистрах сведений.
- Читать их из файла и записывать в файл.
- Передавать их между сервером и клиентом через временное хранилище.
- Инициализировать ими объект типа «Картинка».
- Закодировать и раскодировать в/из строковое представление Base64.
- Хранить в объектах конфигурации в качестве Макета.
- Читать двоичные данные из сети при помощи объектов типа «HTTPСоединение» (объект «HTTPОтвет» можно получить в том числе в виде двоичных данных), «ПочтовоеВложение», «ИнтернетПочтовоеВложение».
- Зашифровать, расшифровать, подписать и проверить подпись средствами криптографии.
- Вычислить хеш-функцию с помощью объекта типа «ХешированиеДанных»
Возможно, я еще что-то упустил, однако интуитивно ясно, что практически все, что надо для работы с двоичными данными в 1С, у нас есть. Рассмотрим теперь по порядку несколько конкретных примеров работы с двоичными данными на платформе 1С 8.3.
Чтение и запись двоичных данных в файл
Основной тип объектов двоичных данных платформы 1С так и называется: «ДвоичныеДанные». Вот что говорит о нем «Синтаксис-помощник»:
Значение содержит двоичные данные, которые считываются из файла. Значение может быть сохранено в ХранилищеЗначения. Хранимые данные могут быть записаны в файл.
Доступность: Тонкий клиент, веб-клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение(клиент), мобильное приложение(сервер).
Сериализуется. Данный объект может быть сериализован в/из XML. Может использоваться в реквизитах управляемой формы.
Чтение двоичных данных из файла
Тип «Двоичные данные» имеет единственный конструктор:
имяФайла — обязательный аргумент.
В итоге получаем программный объект двоичных данных, прочитанный из файла.
Запись двоичных данных в файл
Определение размера двоичных данных в байтах
Сохранение двоичных данных в реквизит объекта
Рассмотрим сразу запись двоичных данных из файла на клиенте в реквизит объекта базы данных типа ХранилищеЗначения. Причем напишем такой код, который сработает и на веб-клиенте, а также будет лишен модальных вызовов, то есть таких вызовов, которые ожидают действия пользователя и останавливают при этом исполнение программы. Теперь платформа 1С 8.3 требует разрабатывать асинхронные программы.
Выглядит это примерно так: создается обработчик оповещения о выполнении некоторой длительной процедуры, затем запускается процедура «НачатьХХХ()», в которую, кроме понятных аргументов, передается еще и описание обработчика ее завершения. Наша программа спокойно работает далее, а по завершении запущенной процедуры вызывается наш обработчик завершения.
Предположим, у нас на форме есть реквизит типа «СправочникСсылка.Картинки». Справочник «Картинки» имеет реквизит «ДанныеКартинки» типа ХранилищеЗначения.
Создадим команду формы «ЗагрузитьКартинкуИзФайла».
Создадим обработчик команды, выделив команду в списке команд формы и нажав на кнопку с увеличительным стеклом в поле «Действие» панели свойств:
Поскольку все необходимые параметры для записи картинки мы можем передать изнутри клиентской части обработчика, нам нет нужды создавать контекстную серверную процедуру на сервере. Выберем «Создать на клиенте и процедуру на сервере без контекста»:
Вначале напишем наши обработчики команды в старом, «модальном» или «синхронном» стиле:
Получите 267 видеоуроков по 1С бесплатно:
В моей небольшой тестовой конфигурации этот код отлично сработал в режиме тонкого клиента. Теперь преобразуем модальный вызов «ПоместитьФайл» в асинхронный, он же немодальный. В меню конфигуратора запустим команду меню «Текст >Рефакторинг >Нерекомендуемые синхронные вызовы >Преобразовать вызовы модуля». Нам в ответ сообщат, что «Не рекомендуемых синхронных вызовов преобразовано: 1».
Для компактности я удалил все пустые строки, и вот что получилось вместо клиентской части нашего обработчика:
Готово! Мы кошерно асинхронно записали картинку из файла на клиенте в реквизит объекта базы данных, в нашем случае — элемента справочника.
Чтение двоичных данных из объекта БД
Для чего нам надо читать двоичные данные из объекта БД? Наверное, три самых частых случая таковы:
- Внедрить картинку в табличный документ, например, отчет. Табличный документ (отчет) часто формируется на стороне сервера, поэтому нам нет нужды гонять картинки через временное хранилище. Мы просто получаем значение из реквизита типа «хранилище значения», инициализируем им объект типа «Картинка» и помещаем эту картинку в табличный документ. А клиентская сторона приложения отображает уже сформированный табличный документ.
- Отобразить на форме некоторую картинку. Нам надо передать двоичные данные на сторону клиента и загрузить их в реквизит формы при открытии формы. Ну и желательно обновлять картинку по некоторым событиям.
- Сохранить двоичный файл на стороне клиента. Здесь надо получить данные с сервера по некоторой команде и просто сохранить их в файл на клиенте.
Пример 1. Вставить картинки в макет (табличный документ).
Допустим, у нас есть база данных со справочником «Картинки», у элементов которых есть реквизит «Картинка» типа ХранилищеЗначения, содержащий данные картинки.
Создадим новую внешнюю обработку, ее основную форму.
На форме создадим 3 реквизита «СпрКартинка1», «СпрКартинка2», «СпрКартинка3» типа «СправочникСсылка.Картинки» и реквизит «ТабДок» типа «ТабличныйДокумент». Перетащим мышкой эти реквизиты в список элементов формы, чтобы на ней образовались соответствующие поля.
Добавим команду формы «НапихатьКартинок» и создадим ее обработчик. На сей раз выберем «Создать на Клиенте и процедуру на сервере», чтобы не передавать много параметров в процедуру без контекста. Напишем такие обработчики:
И получим примерно такой результат:
Пример 2. Показать картинку из базы данных на форме.
Для демонстрации воспользуемся первой обработкой, где мы записывали файл в БД. Теперь покажем на форме картинку, которая записана в реквизите «Картинка» выбранного на форме элемента справочника «Картинки».
Во-первых, добавим на форму поле, связанное с реквизитом «АдресДанныхКартинки». Например, перетащим мышкой этот реквизит в список элементов формы. Выберем и установим значение свойства «Вид» этого поля в «Поле картинки».
Во-вторых, напишем такую серверную процедуру:
И станем вызывать эту процедуру, например, из обработчика события «При изменении» поля «Картинка»:
Сохранение двоичных данных в файл на клиенте
Думаю, с сохранением двоичных данных из базы данных в файл у Вас проблем не возникнет. По крайней мере, если Вы работаете не в веб-клиенте. Читаем, помещаем во временное хранилище на сервере, затем записываем в файл на клиенте.
Кодирование двоичных данных в формат Base64 и обратно
Тут все очень просто. Платформа имеет две глобальные функции, доступные везде:
Первая получает в качестве аргумента объект типа «ДвоичныеДанные», а возвращает его текстовое представление в кодировке base64, а вторая, наоборот, из текста в формате base64 возвращает объект типа «ДвоичныеДанные».
Не очень, правда, представляю, зачем нам это может понадобиться. Во всех встроенных типах объектов вроде ПочтовоеВложение или объектов для работы с XML необходимые преобразования платформа делает сама. Разве что нам потребуется работать с какими-то нестандартными форматами файлов для обмена с внешними системами…
Итого
На самых простых примерах мы увидели все основные принципы и методы работы с двоичными данными в 1С 8.3. Также коснулись актуальной сейчас темы устранения синхронных вызовов. Остальные возможности работы с двоичными данными Вы без труда реализуете по аналогии с рассмотренными здесь.
Спасибо за внимание. Желаю всем вершин профессионализма и глубин познаний. А главное — чтобы это приносило счастье в жизнь Вашу и окружающих.
Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте подписаться на YouTube — регулярно выходят новые видео):
К сожалению, мы физически не можем проконсультировать бесплатно всех желающих, но наша команда будет рада оказать услуги по внедрению и обслуживанию 1С. Более подробно о наших услугах можно узнать на странице Услуги 1С или просто позвоните по телефону +7 (499) 350 29 00. Мы работаем в Москве и области.