Как выгрузить картинки из 1С в XML-файл и загрузить их в другую базу

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Перенос графических данных и файлов между базами 1С — типовая задача при интеграциях, миграциях данных или синхронизации распределенных информационных систем. Чаще всего изображения хранятся в реквизитах типа ХранилищеЗначения (например, в справочнике ХранилищеДополнительнойИнформации или в присоединенных файлах).

Разберем основные способы выгрузки таких объектов в файл формата XML и их последующей корректной загрузки в базу-приемник, а также проанализируем важные нюансы оптимизации памяти и сохранения ссылочной целостности.

Способ 1. Преобразование двоичных данных в Base64-строку

Посмотрим на классический и наиболее наглядный вариант: получение двоичных данных из хранилища, перевод их в текстовое представление с помощью встроенных функций платформы Base64Строка() и последующее обратное преобразование функцией Base64Значение() при загрузке.

Рассмотрим пример кода для выгрузки изображения в XML-документ:


// Извлекаем двоичные данные из ХранилищаЗначения
ДвоичныеДанныеКартинки = Выборка.Картинка.Получить();

Если ДвоичныеДанныеКартинки <> Неопределено Тогда
    КартинкаСтрокой = Base64Строка(ДвоичныеДанныеКартинки);
    ЗаписьXML.ЗаписатьНачалоЭлемента("Картинка");
    ЗаписьXML.ЗаписатьТекст(КартинкаСтрокой);
    ЗаписьXML.ЗаписатьКонецЭлемента();
КонецЕсли;

Разберем, как прочитать эти данные на стороне базы-приемника и записать обратно в реквизит объекта:


// Читаем текстовое значение из XML и создаем новое хранилище
КартинкаСтрокой = ЧтениеXML.Значение;
ДвоичныеДанныеКартинки = Base64Значение(КартинкаСтрокой);

НовыйЭлемент = Справочники.ХранилищеДополнительнойИнформации.СоздатьЭлемент();
НовыйЭлемент.Наименование = ИмяФайла;
НовыйЭлемент.Хранилище = Новый ХранилищеЗначения(ДвоичныеДанныеКартинки, СтепеньСжатия.Максимальное);
НовыйЭлемент.Записать();

Способ 2. Потоковая сериализация через методы ЗаписьXML и ПрочитатьXML

Платформа 1С:Предприятие умеет автоматически сериализовать объекты типа ХранилищеЗначения непосредственно через низкоуровневые объекты ЗаписьXML и ЧтениеXML. В этом случае кодирование в Base64 происходит под капотом платформы без необходимости ручного вызова функций конвертации.

Посмотрим на пример выгрузки реквизита:


Если ТипЗнч(ВыгружаемыйРеквизит) = Тип("ХранилищеЗначения") Тогда
    ЗаписьXML.ЗаписатьНачалоЭлемента("РеквизитХранилище");
    ЗаписьXML.ЗаписатьАтрибут("Тип", "ХранилищеЗначения");
    ЗаписатьXML(ЗаписьXML, ВыгружаемыйРеквизит);
    ЗаписьXML.ЗаписатьКонецЭлемента();
КонецЕсли;

Проанализируем чтение такого узла в базе-приемнике:


Если ЧтениеXML.Имя = "РеквизитХранилище" И ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
    ТипРеквизита = ЧтениеXML.ПолучитьАтрибут("Тип");
    Если ТипРеквизита = "ХранилищеЗначения" Тогда
        ЧтениеXML.Прочитать(); // Переходим к содержимому элемента
        ДанныеХранилища = ПрочитатьXML(ЧтениеXML);
        ОбъектПриемник.Хранилище = ДанныеХранилища;
    КонецЕсли;
КонецЕсли;

Способ 3. Использование объекта СериализаторXML

Для автоматической сериализации прикладных объектов и сложных структур данных можно применить встроенный объект СериализаторXML. Он позволяет трансформировать реквизиты или значения типа ДвоичныеДанные напрямую в формат XML.


// Выгрузка двоичных данных через СериализаторXML
ДвоичныеДанныеФайла = Выборка.Хранилище.Получить();
Если ДвоичныеДанныеФайла <> Неопределено Тогда
    СериализаторXML.ЗаписатьXML(ЗаписьXML, ДвоичныеДанныеФайла);
КонецЕсли;

Чтение выполняется парным методом СериализаторXML.ПрочитатьXML(ЧтениеXML), возвращающим исходный объект ДвоичныеДанные.

Способ 4. Типовая обработка «Выгрузка и загрузка данных XML»

Если обе информационные базы имеют полностью идентичную конфигурацию, писать собственный программный код не обязательно. Достаточно использовать типовую универсальную обработку «Выгрузка и загрузка данных XML» (доступную на ИТС):

  1. Открываем обработку в исходной информационной базе.
  2. В дереве метаданных отмечаем справочник, хранящий изображения (например, ХранилищеДополнительнойИнформации или справочники присоединенных файлов), а также связанные с ним объекты-владельцы (номенклатуру, контрагентов и т.д.).
  3. Выполняем выгрузку в XML-файл. Обработка автоматически сериализует все двоичные данные и ссылки.
  4. В базе-приемнике открываем ту же обработку в режиме загрузки и читаем сформированный файл.

Важные технические особенности и оптимизация

При реализации выгрузки и загрузки больших объемов графических данных необходимо учитывать несколько критических факторов:

  1. Рост объема данных: При кодировании двоичных данных в формат Base64 размер текста возрастает примерно на 33% по сравнению с исходным бинарным файлом. Это следует учитывать при планировании свободного места на диске.
  2. Контроль оперативной памяти: Категорически не рекомендуется использовать объектную модель ДокументDOM для файлов большого объема, так как она загружает весь XML-документ целиком в оперативную память. Используйте исключительно потоковое чтение и запись через ЗаписьXML и ЧтениеXML.
  3. Порционная запись и транзакции: Выполняйте обработку пачками (например, по 50–100 элементов) с явным вызовом НачатьТранзакцию() и ЗафиксироватьТранзакцию(), чтобы не перегружать журнал транзакций СУБД.
  4. Сохранение ссылочной целостности: Если перенос выполняется собственным кодом, перед записью нового элемента в базе-приемнике обязательно вызывайте метод УстановитьСсылкуНового() с исходным уникальным идентификатором (UUID) объекта из базы-источника. Это гарантирует сохранение всех ссылок на владельцев.
  5. Сжатие в хранилище: При создании объекта Новый ХранилищеЗначения(...) передавайте параметр СтепеньСжатия.Максимальное или СтепеньСжатия.Быстрое для оптимизации размера базы данных.

Альтернативные варианты обмена

Если файлы слишком велики для передачи через текстовый XML, рассмотрим альтернативные механизмы:

  1. HTTP-сервисы (REST API): Передача изображений в бинарном виде через тело HTTP-запроса без накладных расходов на Base64-кодирование.
  2. Прямое COM-соединение: Чтение двоичных данных из базы-источника через V83.COMConnector и прямая запись в приемник без создания промежуточных файлов на диске.
  3. Планы обмена: Настройка регулярного обмена между узлами, где платформа берет на себя отслеживание изменений и сериализацию данных.
← На главную