Перейти к содержимому

1с где можно хранить двоичные данные

  • автор:

Двоичные данные в 1С 8.3

Анна Викулина

Двоичные данные платформы 1С:Предприятие – это универсальный объект встроенного языка программирования для работы с файлами. Благодаря объекту ДвоичныеДанные можно любой файл представить в виде последовательности байт. Объект доступен в тонком клиенте, веб-клиенте, мобильном клиенте, на сервере, толстом клиенте, внешнем соединении, мобильном приложении (клиент/сервер).

Объект сериализуется

Данный объект может быть сериализован в/из XML, может использоваться в реквизитах управляемой формы, а также он может быть сериализован в/из XDTO. Тип XDTO, соответствующий данному объекту, определяется в пространстве имен . Имя типа XDTO может быть любым из перечисленных: base64Binary, hexBinary.

Благодаря тому, что двоичные данные доступны и на клиенте, и на сервере, мы можем смело передавать файл в виде двоичных данных с клиента на сервер, однако рекомендованный «шаблон» для передачи файла – использовать хранилище значений.

Задачи, для решения которых можно использовать двоичные данные:

  • Хранение файлов в базе данных (с использованием ХранилищеЗначения);
  • Передача файла с клиента на сервер;
  • Передача файлов при работе с протоколом HTTP;
  • Передача вложений при работе с электронными письмами;
  • Криптография;
  • Представления файла в виде текста (с использованием Base64).

Работа с двоичными данными:

 &НаКлиенте Процедура ПередатьФайлНаСервер() Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие); Диалог.МножественныйВыбор = Ложь; Если Диалог.Выбрать() ТОгда БинДанные = Новый ДвоичныеДанные(Диалог.ПолноеИмяФайла); АдресВременногоХранилища = ПоместитьВоВременноеХранилище(БинДанные, ЭтаФорма.УникальныйИдентификатор); ОбработкаФайлаНаСервере(АдресВременногоХранилища); КонецЕсли; КонецПроцедуры &НаСервереБезКонтекста Процедура ОбработкаФайлаНаСервере(АдресВХ) БинДанные = ПолучитьИзВременногоХранилища(АдресВХ); Если БинДанные <> Неопределено Тогда //БинДанные.Записать("Путь файла на сервере"); КонецЕсли; КонецПроцедуры

Данный пример кода показывает, как прочитать двоичные данные и передать их с клиента на сервер, используя объект ДвоичныеДанные.

Примеры по работе с двоичными данными

Самый очевидный пример, где применяются двоичные данные, – сохранение файла в базе данных. Для хранения файла в виде двоичных данных необходимо в объекте добавить реквизит с типом «ХранилищеЗначений». Далее представлен пример кода по работе с реквизитом (заполнение значения и получение значения).

Заполнение:

 ПутьКФайлу = ""; БинДанные = Новый ДвоичныеДанные(ПутьКФайлу); Объект.Файл = Новый ХранилищеЗначения(БинДанные);

Получение (фрагмент кода, выполняемый на сервере):

 БинДанные = Объект.Файл.Получить(); Если БинДанные <> Неопределено Тогда // БинДанные.Записать(Имя Файла); // или // Поток = БинДанные.ОткрытьПотокДляЧтения(); КонецЕсли

Рассмотрим еще один пример: скачивание картинки из интернета и отображение ее на управляемой форме. Для этого также добавляем реквизит с типом ХранилищеЗначения, в котором будет помещаться картинка в двоичном формате.

Скачивание картинки из интернета

Функция, скачивающая картинку из интернета:

 Функция СкачатьКартинку(URL) СтруктураURI = ОбщегоНазначенияКлиентСервер.СтруктураURI(URL); ФайлОтвет = ПолучитьИмяВременногоФайла(); HTTPСоединение = Новый HTTPСоединение(СтруктураURI.ИмяСервера); HTTPЗапрос = Новый HTTPЗапрос(СтруктураURI.ПутьНаСервере); Ответ = HTTPСоединение.Получить(HTTPЗапрос, ФайлОтвет); Если Ответ.КодСостояния = 200 Тогда Возврат Новый ДвоичныеДанные(ФайлОтвет); КонецЕсли; КонецФункции

Использование функции:

 БинДанные = СкачатьКартинку("url картинки"); СпрОбъект.Аватар = Новый ХранилищеЗначения(БинДанные); СпрОбъект.Записать();

Теперь у нас в реквизите «Аватар» лежат двоичные данные картинки. Чтобы картинку вывести на управляемую форму, необходимо добавить реквизит формы «Тип строка», перекинуть его на форму (drag-and-drop), либо создать самостоятельно элемент формы, указав в поле «Путь к данным» наш реквизит «Картинка», после чего изменить вид на «Поле картинки».

Поле картинки

По событию ПриСозданииНаСервере

 СпрОбъект = РеквизитФормыВЗначение("Объект"); Картинка = ПолучитьНавигационнуюСсылку(СпрОбъект, "Аватар");

Готово, на форме у нас картинка.

Двоичные данные и потоки

Говоря о двоичных данных, стоит упомянуть о возможности работы с потоками. Она появилась относительно недавно, а именно в версии 8.3.9. Чтобы потоком можно было читать из двоичных данных, применяется метод ОткрытьПотокДляЧтения. Допустим, у нас в базе данных лежит заархивированный xml-файл (как хранить файлы в базе данных рассматривалось ранее). Нам нужно вывести пользователю содержимое этого файла, или у вас настроен какой-то обмен, и вы передаете файлы в заархивированном виде (для экономии трафика).

Последовательность действий при работе с двоичными данными без использования потоков:

  • Получить двоичные данные из базы;
  • Записать их во временный файл;
  • Разархивировать;
  • Удалить временный файл;
  • Прочитать разархивированный файл.

Последовательность действий при работе с потоками:

  • Получить двоичные данные из базы;
  • Открыть поток для чтения;
  • Разархивировать;
  • Прочитать разархивированный файл.

Пример кода без использования потоков:

 Процедура ОбработкаФайлаНаСервере(АдресВХ) БинДанные = ПолучитьИзВременногоХранилища(АдресВХ); ВрФайл = ПолучитьИмяВременногоФайла("zip"); Если БинДанные <> Неопределено Тогда БинДанные.Записать(ВрФайл); ПолучитьФайлыАрхива(ВрФайл); УдалитьФайлы(ВрФайл); КонецЕсли; КонецПроцедуры Функция ПолучитьФайлыАрхива(ВрФайл) Результат = Новый Массив(); ЧтениеZipФайла = Новый ЧтениеZipФайла(ВрФайл); ЧтениеZipФайла.ИзвлечьВсе("Путь к каталогу", РежимВосстановленияПутейФайловZIP.Восстанавливать); ЧтениеZipФайла.Закрыть(); КонецФункции 

Пример кода по работе с потоком:

 Процедура ОбработкаФайлаНаСервере(АдресВХ) БинДанные = ПолучитьИзВременногоХранилища(АдресВХ); Если БинДанные <> Неопределено Тогда ПолучитьФайлыАрхива(БинДанные); КонецЕсли; КонецПроцедуры Функция ПолучитьФайлыАрхива(БинДанные) Результат = Новый Массив(); ЧтениеZipФайла = Новый ЧтениеZipФайла(БинДанные.ОткрытьПотокДляЧтения()); ЧтениеZipФайла.ИзвлечьВсе("Путь к каталогу", РежимВосстановленияПутейФайловZIP.Восстанавливать); ЧтениеZipФайла.Закрыть(); КонецФункции

Если диск у вас на SSD, рекомендую использовать потоки не только в примере с архивацией, а везде, где это возможно. Да, в данном примере все же происходит запись на диск (разархивация), но будем надеяться, когда-нибудь 1С реализует метод двоичных данных ОткрытьПотокДляЗаписи.

Работа с Base64

Base64 – это стандарт, позволяющий кодировать двоичные данные в виде строки (для кодирования используется 64 символа таблицы ASCII, отсюда и название). Тип ДвоичныеДанные сериализуем, то есть его можно представить в виде XML, для этого применяется объект встроенного языка СериализаторXDTO. После сериализации данные представлены одним узлом base64Binary, содержимое которого есть последовательность байт, закодированная в формате Base64.

строка в Base64

Платформа 1С также позволяет кодировать двоичные данные, не прибегая к сериализации. Для этого есть две функции:

Они преобразуются в Base64 и обратно в двоичные данные.

Если у вас остались вопросы по работе с двоичными данными в среде 1С:Предприятие, обратитесь к нашим специалистам и получите консультацию по 1С 8.3 или воспользуйтесь услугами по сопровождению 1С.

Хранилище двоичных данных

В версии 8.3.23 в платформе появится новый механизм – хранилище двоичных данных.
Этот механизм предназначен для хранения больших двоичных (Binary Large Objects, BLOB) не в базе данных, а в специализированном хранилище.

Решаемая задача

Часто задачи информационных баз включают в себя не только хранение и обработку интерактивно вносимых данных, но и требуют связки с различными прилагаемыми файлами (сканами документов, фотографиями, аудио- и видеозаписями и т.п.). Например, в 1С:Документообороте к создаваемому договору необходимо приложить скан бумажной версии.
Хранение больших двоичных данных в СУБД влечет ряд проблем, в частности:

  • Двоичные данные хранятся в используемой СУБД вместе с остальной информацией, при этом работа с этими данными конкурирует вместе с остальными операциями в базе данных, что может приводить к высокой нагрузке на аппаратные мощности и, возможно, к падению производительности системы.
  • Хранение больших двоичных данных в СУБД ведет к росту объёма базы, что, в свою очередь, вызывает сложности в эксплуатации самой системы:
    • Проблемы с бэкапом и восстановлением БД.
    • Проблемы с масштабированием системы.
    • Увеличенные сроки обновления и обслуживания БД (долгая дефрагментация и реструктуризация).

    img-01.png

    Использование механизма

    img-02.png

    В стандартных обработках (доступных из пункта меню «Функции для технического специалиста») появится обработка «Управление хранилищем двоичных данных». В этой обработке можно включить и настроить новый механизм.

    У конфигурации, начиная с режима совместимости 8.3.10, появится свойство “Использование хранилища двоичных данных”. При установке этого свойства в «Использовать» все реквизиты типа ХранилищеЗначений, чей размер больше указанного в настройках, будут сохранены в хранилище двоичных данных (при условии, что использование хранилища двоичных данных включено и у хранилища не установлен режим «Только чтение»).
    Включение хранилища двоичных данных для конкретной информационной базы приведет к тому, что часть данных будет храниться как и раньше в СУБД, а часть — в специальном каталоге кластера серверов 1С:Предприятие. Поэтому рекомендуется выполнять резервное копирование и базы данных, и «Хранилища двоичных данных».
    Механизм хранилища двоичных данных доступен только в клиент-серверном варианте работы.
    Использование хранилища двоичных данных абсолютно прозрачно для разработчиков и конечных пользователей; не надо задумываться над тем, используется хранилище или нет, и не надо ничего модифицировать в конфигурации.
    Сейчас использовать механизм хранилища двоичных данных могут только участники программы бета-тестирования. Чтобы стать участником программы бета-тестирования нажмите зелёную кнопку «Пробовать» в начале статьи.

    Двоичные данные в 1С

    В статье рассматриваются двоичные данные, способы их хранения в 1С, примеры использования, а также примеры программного кода для работы с двоичными данными.

    Что хранится в двоичных данных?

    Если совсем кратко – все что угодно. Картинки, внешние обработки, документы, внешние компоненты, и т.д. Платформа “не знает”, что содержится в двоичном файле, и реализация логики ложится на плечи разработчика – он сам должен решить, как эти данные обрабатывать, и что они из себя представляют в каждом случае.

    Где хранить двоичные данные в базе 1С?

    Двоичные данные можно хранить несколькими способами.

    В макетах с типом “Двоичные данные”, в объектах конфигурации. В этом случае запись двоичных данных в макет производится еще на этапе разработки конфигурации.

    В реквизитах с типом ХранилищеЗначения, в объектах базы данных, например, в справочниках, регистрах сведений, документах.

    В реквизитах типа строка, в формате base64, в Base 16 (Hex), либо в виде строки в указанной кодировке. Рассмотрим пример. Допустим, у нас есть текстовый файл с содержимым “Тест тест тест”, который мы прочитали в виде двоичных данных в переменную ДД. Платформа предусматривает несколько методов получения строки из двоичных данных, каждому из которых соответствует обратный метод – формирование двоичных данных из строки того или иного формата.

    Где применяются двоичные данные в 1С?

    Чаще всего, двоичные данные в 1С используются в следующих случаях:

    • Внешние компоненты – для подключения торгового оборудования, или для решения задач, которые средствами платформы сложно или вовсе невозможно решить;
    • Хранение файлов внешних отчетов и обработок;
    • Вывод изображений на форму (на экран) или в печатный документ;
    • Прикрепленные файлы – любые файлы, имеющие отношение к конкретным объектам базы – например, сканы договоров, презентации, документы, и т.д.
    • вложения электронных писем или html-документов
    • шифрование и использование криптографии, в частности, электронные подписи
    • получение файлов по сети, например при помощи http-сервисов
    • Хранение xml-файлов – например, настроек обмена, xml-схем, и т.д.

    Как работать с двоичными данными в 1С?

    При работе с двоичными данными в 1С, следует понимать, что это промежуточное “агрегатное состояние” данных. Сами они нигде не хранятся, а размещаются полностью или частично в оперативной памяти. Получить двоичные данные можно множеством способов. Вот лишь некоторые:

    • получить из строки (см. выше)
    • прочитать из реквизита с типом ХранилищеЗначения:
      НужнаяНоменклатура = Справочники.Номенклатура.НайтиПоНаименованию(“Нужная номенклатура”);
      ДвоичныеДанные = НужнаяНоменклатура.ХранилищеДвоичныхДанных.Получить();
    • Получить как тело ответа http-сервиса:
      //HTTPОтвет = результат выполнения http-запроса.
      HTTPОтвет.ПолучитьТелоКакДвоичныеДанные()
    • Получить как данные почтового вложения
      ПочтовоеВложение.Данные
    • Получить как исходные данные интернет почтового сообщения
      ИнтернетПочтовоеСообщение.ПолучитьИсходныеДанные

    Следующее, что чаще всего делают с двоичными данными – это либо записывают в базу, либо сохраняют в файл.
    Записать в базу можно в реквизит с типом ХранилищеЗначения:

    дд = Новый ДвоичныеДанные(ПутьКФайлу);
    СпрКартинка = Справочники.Картинки.Картинка; //Картинка – реквизит с типом ХранилищеЗначения
    Об = СпрКартинка.ПолучитьОбъект();
    Об.Картинка = Новый ХранилищеЗначения(дд);
    Об.Записать();

    Либо в реквизит с типом Строка неограниченной длины. О том, как преобразовать двоичные данные в строку – чуть выше.
    Ну и кроме того, двоичные данные нужны для того, чтобы сохранить их в файл. Для того чтобы это сделать, предусмотрены целых три метода!

    • Записать – стандартный синхронный метод, который записывает двоичные данные в файл. При этом платформа будет ожидать окончания выполнения записи, прежде чем продолжить выполнение кода.
    • НачатьЗапись – асинхронная процедура, которая не блокирует выполнение кода. При этом по завершении записи в файл, будет вызвана процедура-обработчик.
    • ЗаписатьАсинх – новый вариант асинхронной записи, появившийся в версии 8.3.18.

    Потоки и побитовые операции с двоичными данными в 1С.

    Помимо записи в файл, с двоичными данными можно работать при помощи потоков. Потоки – это отдельный механизм платформы, достойная отдельной статьи. Здесь отмечу лишь, что потоки позволяют обрабатывать очень большие объемы данных за счет последовательной записи и чтения.
    Также, потоки позволяют избежать использования временных файлов, выполняя все операции с данными в оперативной памяти.

    Двоичные данные можно объединять, разделять, получать часть данных в виде буфера в оперативной памяти, а также выполнять побитовые операции. Побитовые операции имеют довольно узкую специфику применения, и используются не так часто. Например, для генерации QR кодов, ключей шифрования, картинок, или при декодировании формата обмена с торговым оборудованием.

    На этом все, надеюсь, статья структурировала ваше представлении о двоичных данных, и была хоть немного полезна.

    Сохранение и восстановление данных в Хранилище значений.

    Хранилище значений — это тип, который появился в 8-ой версии 1С позволяющий сохранять прямо в базе различные данные, включая двоичные данные (произвольные файлы). Например, так можно хранить в базе данных JPG-картинки, Word-документы и т.д. Причем данные будут храниться в самой базе (файле 1CD или в таблицах на SQL-сервере) и будут включены в штатную выгрузку базы или резервную копию средствами SQL Server.

    Тип Хранилище значения может быть назначен реквизиту справочника, документа, ресурсу регистра сведений и т.д.

     //Изображение, картинки (фотки): 

    ТекИзображение.Объект = СпрТкани.Ссылка;
    ТекИзображение.ВидДанных = Перечисления.ВидыДополнительнойИнформацииОбъектов.Изображение;
    Хранилище = Новый ХранилищеЗначения(НоваяКартинка, Новый СжатиеДанных());
    ТекИзображение.Хранилище = Хранилище.Получить();

    // в этом месте он все выводит .

    ЭлементыФормы.ПолеКартинки1.Картинка = Хранилище.Получить();
    ТекИзображение.Записать();
      
    //Табличный документ:
    Процедура СохранитьВХранилищеНажатие(Элемент)
    ТабДок=Новый ТабличныйДокумент;
    ТабДок.Вывести(ЭлементыФормы.ПолеТабличногоДокумента1);
    Хранилище=Новый ХранилищеЗначения(ТабДок);
    Записать();
    КонецПроцедуры

    Процедура ВосстановитьИзХранилищаНажатие(Элемент)
    ТабДок=Хранилище.Получить();
    Если ТабДок<>Неопределено Тогда
    ЭлементыФормы.ПолеТабличногоДокумента1.Вывести(ТабДок);
    КонецЕсли;
    КонецПроцедуры
     //Произвольные файлы (двоичные данные): 

    ХЗ = Новый ХранилищеЗначения(Новый ДвоичныеДанные(файл));

    Восьмерка поддерживает сжатие данных, помещаемых в хранилище:

     ХЗ = Новый ХранилищеЗначения(Новый ДвоичныеДанные(файл),Новый СжатиеДанных(9)); 
     //Внешние обработки и отчеты: 

    Процедура ЗагрузитьОбработкуВХранилище(РеквизитТипХранилище)
    СтепеньСжатия = Новый СжатиеДанных(9); //9 максимум
    РеквизитТипХранилище = Новый ХранилищеЗначения(Новый ДвоичныеДанные("c:\отчеты\отчет.epf", СтепеньСжатия));
    КонецПроцедуры

    Процедура ЗапуститьОбработкуИзХранилища(РеквизитТипХранилище)
    ИмяВременногоФайла = КаталогВременныхФайлов()+"отчет.epf";
    ДвоичныеДанные = РеквизитТипХранилище.Получить();
    ДвоичныеДанные.Записать(ИмяВременногоФайла);
    ВнешняяОбработка = ВнешниеОбработки.Создать(ИмяВременногоФайла);
    ВнешняяОбработка.ПолучитьФорму().Открыть();
    КонецПроцедуры

    Если это были ДвоичныеДанные, то их можно восстановить из хранилища значения методом Получить и записать в файл методом Записать().

    Аренда 1С в облаке

     Если ТипЗнч(Хранилище) <> Тип("ДвоичныеДанные") Тогда 
    ДвоичныеДанные = Хранилище.Получить();
    Иначе
    ДвоичныеДанные = Хранилище;
    КонецЕсли;
    ДвоичныеДанные.Записать(ИмяФайла);

    Если это был, например, Word-документ (doc-файл, или другой файл зарегистрированного типа), то его можно открыть так:

     ЗапуститьПриложение(ИмяФайла); 

    Чтобы очистить поле типа Хранилище значения, нужно присвоить ему Неопределено:
    Код 1C v 8.х

     РеквизитХранилище = Неопределено; 

    Если в Хранилище значений содержались какие-то ссылки, то они не будут контролироваться при контроле ссылочной целостности (операция Удаление помеченных объектов или метод НайтиПоСсылкам).

    К сожалению, 1С не содержит встроенных методов для проверки того, заполнено хранилище или нет.
    Такой вариант не работает:
    Код 1C v 8.х

     фл=Хранилище<>Неопределено; 

    Работает только такой вариант:
    Код 1C v 8.х

     фл=Хранилище.Получить()<>Неопределено; 

    Но он требует затрат времени на извлечение данных из хранилища.
    Поэтому, если это критично, нужно заводить еще один флаг, который указывает, содержит ли хранилище значение.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

https://kodirovanie.vyvod-iz-zapoya-na-domu-moskva-snp.ru/