Значение в строку внутреннюю для сложных типов: как работает платформа или немного о декодировании base64 в текст через двоичные данные

28.04.17

Разработка - Механизмы платформы 1С

Интересная особенность работы платформы со сложными типами при использовании метода ЗначениеВСтрокуВнутр, двоичные данные и новые методы платформы...

Добрый день всем!

Вот столкнулся с такой штукой, как "сериализация" фильтра компоновки данных с помощью метода "ЗначениеВСтрокуВнутр" платформы. Суть в том, что платформа сначала сериализует данный объект в XML, а затем этот XML кодирует в base64 и помещает в некий JSON-контейнер с типом и данными. Тип - это некий идентификатор, а данные - это тот самый закодированный в base64 сериализованный XML.

Рассуждать на тему того, почему 1С решили сделать таким образом, особого смысла нет - сделали - и слава Богу!* Но вот решил я все-таки декодировать base64-строку в текст и не нашел соответствующего метода платформы. В двоичные данные - пожалуйста, а в текст - нет. Но в последних релизах платформы объект "ДвоичныеДанные" оброс знатным функционалом, что просто не могло не обрадовать многих специалистов по 1С. В итоге родился такой вот замечательный код:

// Данные - это что-то, что было сериализовано с помощью "ЗначениеВСтрокуВнутр"
Поз = СтрНайти(Данные, "#base64");
ПС = Сред(Данные, поз+8);
Поз2 = СтрНайти(ПС, "}");
ПС = Лев(ПС, Поз2-1);
ЧД = Новый ЧтениеДанных(Base64Значение(ПС));
СтрокаXML = ЧД.ПрочитатьСимволы();

У нас тут есть, допустим, какие-то данные, которые мы откуда-то взяли. Например:

Данные = ЗначениеВСтрокуВнутр(ОтборКомпоновкиДанных);

В итоге у нас получилась какая-то такая строка:

{"#",f6841c6b-6c71-4c82-ae9e-d08b49db326c,
{#base64:77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxGaWx0
ZXIgeG1sbnM9Imh0dHA6Ly92OC4xYy5ydS84LjEvZGF0YS1jb21wb3NpdGlvbi1z
eXN0ZW0vc2V0dGluZ3MiIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAx
L1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hN
TFNjaGVtYS1pbnN0YW5jZSI+DQoJPGl0ZW0geHNpOnR5cGU9IkZpbHRlckl0ZW1H
cm91cCI+DQoJCTxncm91cFR5cGU+QW5kR3JvdXA8L2dyb3VwVHlwZT4NCgkJPGl0
ZW0geHNpOnR5cGU9IkZpbHRlckl0ZW1Db21wYXJpc29uIj4NCgkJCTxsZWZ0IHht
bG5zOmRjc2Nvcj0iaHR0cDovL3Y4LjFjLnJ1LzguMS9kYXRhLWNvbXBvc2l0aW9u
LXN5c3RlbS9jb3JlIiB4c2k6dHlwZT0iZGNzY29yOkZpZWxkIj7QodGH0LXRgtCU
0YIu0JrQvtC0PC9sZWZ0Pg0KCQkJPGNvbXBhcmlzb25UeXBlPkNvbnRhaW5zPC9j
b21wYXJpc29uVHlwZT4NCgkJCTxyaWdodCB4c2k6dHlwZT0ieHM6c3RyaW5nIj4x
MDYuMDE8L3JpZ2h0Pg0KCQk8L2l0ZW0+DQoJCTxpdGVtIHhzaTp0eXBlPSJGaWx0
ZXJJdGVtQ29tcGFyaXNvbiI+DQoJCQk8bGVmdCB4bWxuczpkY3Njb3I9Imh0dHA6
Ly92OC4xYy5ydS84LjEvZGF0YS1jb21wb3NpdGlvbi1zeXN0ZW0vY29yZSIgeHNp
OnR5cGU9ImRjc2NvcjpGaWVsZCI+0KHRg9Cx0LrQvtC90YLQvtCU0YIxLlvQodC4
0LzQstC+0Lsg0J7QpNCgKyDQktC40LTRiyDQvdC+0LzQtdC90LrQu9Cw0YLRg9GA
0YsgXTwvbGVmdD4NCgkJCTxjb21wYXJpc29uVHlwZT5FcXVhbDwvY29tcGFyaXNv
blR5cGU+DQoJCQk8cmlnaHQgeG1sbnM6ZDRwMT0iaHR0cDovL3Y4LjFjLnJ1Lzgu
MS9kYXRhL2VudGVycHJpc2UvY3VycmVudC1jb25maWciIHhzaTp0eXBlPSJkNHAx
OkNhdGFsb2dSZWYu0L3RhNC+X9CX0L3QsNGH0LXQvdC40Y/QkNC90LDQu9C40YLQ
uNC60LgiPmE1Yzg2MjQwLWRmOTMtMTFlNS05NDU2LTAwMWU2NzU0ODlmNDwvcmln
aHQ+DQoJCTwvaXRlbT4NCgk8L2l0ZW0+DQo8L0ZpbHRlcj4=}
}

Дальше мы из этой строки получаем данные base64, которые обрамлены символами "{#base64:" и "}". Т.е. получаем все, что между этими символами.

После этого мы декодируем строку base64 в двоичные данные давно известной функцией. И вот из этих двоичных данных получить строку не так-то просто. Раньше можно было записать файл и потом прочитать его в виде текста. Но операции ввода-вывода достаточно затратны. В новой платформе (у меня 8.3.10.2168) появились функции работы с потоками двоичных данных. Мы здесь используем объект "ЧтениеДанных", который можно создать на основании двоичных данных, полученных с помощью функции "Base64Значение". У объекта "ЧтениеДанных" есть метод "ПрочитатьСимволы()", который без параметров просто возвращает нам в кодировке по-умолчению все символы из двоичных данных. Таким образом, в переменной "СтрокаXML" будет находиться следующее значение:

<?xml version="1.0" encoding="UTF-8"?>
<Filter xmlns="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <item xsi:type="FilterItemGroup">
        <groupType>AndGroup</groupType>
        <item xsi:type="FilterItemComparison">
            <left xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xsi:type="dcscor:Field">СчетДт.Код</left>
            <comparisonType>Contains</comparisonType>
            <right xsi:type="xs:string">106.01</right>
        </item>
        <item xsi:type="FilterItemComparison">
            <left xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xsi:type="dcscor:Field">СубконтоДт1.[Символ ОФР+ Виды номенклатуры ]</left>
            <comparisonType>Equal</comparisonType>
            <right xmlns:d4p1="http://v8.1c.ru/8.1/data/enterprise/current-config" xsi:type="d4p1:CatalogRef.нфо_ЗначенияАналитики">a5c86240-df93-11e5-9456-001e675489f4</right>
        </item>
    </item>
</Filter>

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

ДвоичныеДанные base64 ЗначениеИзСтрокуиВнутр

См. также

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    7462    bayselonarrend    20    

154

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    5947    dsdred    16    

80

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

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

24.01.2024    17676    YA_418728146    26    

71

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    11229    dsdred    44    

130

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    23763    SeiOkami    48    

135

Механизмы платформы 1С Системный администратор Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    18835    human_new    27    

80

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14735    YA_418728146    7    

166
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. mxm2 1268 03.05.17 07:38 Сейчас в теме
Для старых версий платформ работает это: Base64 преобразование туда и обратно без файловых операций (Управляемое приложение). Ваш вариант работает быстрее. Вообще в 8.3.10 много "вкусного" из того, что давно требовалось при разработке.
alevnev; swiss-garant; +2 Ответить
2. rus128 2 03.05.17 12:28 Сейчас в теме
Опечатка: "по-умолчению"
3. starik-2005 3088 11.05.17 17:37 Сейчас в теме
(2)
Опечатка
Ужс...
user1064367; +1 Ответить
Оставьте свое сообщение