Пишу свой движок выгрузки конфигураций 1С в XML: зачем, что уже работает и первые цифры
Интеграция - Файловый обмен (TXT, XML, DBF), FTP
Последние пару лет я много работаю с конфигурациями в виде XML-файлов: git, ветки, загрузка и выгрузка по десятку раз в день. Всё это время между базой и файлами стоит штатный ibcmd (или конфигуратор в пакетном режиме), и чем дальше, тем сильнее хочется заменить его своим кодом.
Недавно я наконец начал. Это первая статья о том, зачем я за это взялся, что уже работает и сколько это стоит по времени.
Зачем
Платформа медленная там, где могла бы быть быстрой. Несколько замеров ibcmd на 8.3.27.2214, файловая база, Ryzen 5 5600G, 32 ГБ, NVMe:
| Операция | УТ 11.6 | ERP 2.6 |
|---|---|---|
| Размер CF | 1,7 ГБ | 2,9 ГБ |
| Файлов в XML-выгрузке | 51 595 | 125 046 |
| Объём выгрузки | 2,78 ГБ | 9,75 ГБ |
Полная выгрузка базы в файлы (config export) |
0:52 | 3:00 |
| CF → XML (временная база, загрузка CF, выгрузка) | 3:22 | 10:38 |
| Полная загрузка из файлов | 2:34–3:15 | 5:52–6:47 |
Больше всего раздражает строка «CF → XML». Чтобы просто посмотреть CF-файл в виде исходников, платформе нужно создать временную базу, загрузить в неё конфигурацию и только потом выгрузить. На ERP это больше десяти минут, хотя по сути нужно распаковать архив и перевести один формат в другой.
Работа без платформы. Для любой операции нужна установленная 1С нужной версии. Для разбора файла она не нужна в принципе.
Интерес. Внутренний формат 1С — это контейнеры, deflate и скобочные структуры {…}. Разобраться, как из этого получается тот XML, который мы видим в выгрузке, — хорошая задача сама по себе.
Что именно я пишу
Движок, который на входе получает файл (CF, CFE, EPF, ERF) или базу, а на выходе отдаёт тот же XML, что и штатная выгрузка. Не «похожий», не «свой удобный формат», а файл в файл, байт в байт. Иначе его нельзя подложить вместо ibcmd: git тут же покажет тысячи изменённых файлов.
Пишу на Rust: большие бинарные файлы, один exe без рантайма и полный контроль над памятью.
Главное правило движка: всё незнакомое — отказ. Если встретилась структура, которую я ещё не сверил со штатной выгрузкой, движок не пытается угадать, а честно отвечает «не умею» и показывает место расхождения. Тогда выгрузку делает платформа. Тихо выгрузить чуть-чуть не то гораздо хуже, чем не выгрузить вообще.
Что уже работает
1. Контейнер v8
CF, CFE, EPF и ERF — это контейнеры: оглавление, цепочки блоков, заголовки элементов, сжатие raw deflate, внутри могут быть вложенные контейнеры. Есть 32-битный и 64-битный формат. Интересная деталь: CF 8.3 — это на самом деле два контейнера подряд. Сначала маленький 32-битный, за ним 64-битный со всей конфигурацией.
Файл отображается в память, а не читается целиком. CF УТ размером 1,8 ГБ движок прочитал целиком, со всеми вложенными контейнерами и распаковкой, за 16 секунд.
Важно: это только чтение контейнера, а не выгрузка в XML. Сравнивать эти 16 секунд с тремя минутами штатного «CF → XML» нельзя: самую сложную часть, превращение внутренних структур в XML, движок для конфигурации ещё не делает. Цифра показывает другое: распаковка CF занимает секунды, а значит, основное время штатного пути уходит не на неё.
2. Скобочный формат
Почти всё внутри контейнера записано в скобочном формате 1С:
{1,{2,"строка ""в кавычках""",…},…}
Парсер работает без копирования и без рекурсии, с ограничением глубины. Он понимает строки с удвоенными кавычками, многострочный base64, пустые значения вида {2,uuid,} и несколько списков на верхнем уровне (так устроен configinfo расширения).
Проверка — на корпусе: разбираются все скобочные файлы из нескольких внешних обработок и отчётов, двух расширений, БСП (7 064 файла) и БПО. Ни одного отказа.
3. Первые объекты в XML: внешние обработки
Начал с самого простого — внешних обработок. Сейчас движок выгружает объект обработки, реквизиты (основные типы: булево, строка, число, СписокЗначений, ТаблицаЗначений, ДеревоЗначений, КомпоновщикНастроек, ссылки), модуль объекта, описание форм и модули форм.
Разбор устроен через «образцы»: для каждой структуры записана известная форма с местами для значений. Если запись хоть чем-то отличается от образца, это отказ с указанием места. Так в XML попадает только то, что уже сверено со штатной выгрузкой.
Как я проверяю
Есть корпус из 208 внешних обработок и отчётов из реальной жизни. Для каждого файла стенд делает две выгрузки:
- штатную — конфигуратором 8.3.27 (
/DumpExternalDataProcessorOrReportToFiles, иерархический формат); - своим движком.
Потом каталоги сравниваются побайтово. Совпадение «почти» не засчитывается.
Ещё одна важная мелочь: стенд дважды выгружает штатно и сравнивает две штатные выгрузки между собой. Если платформа сама с собой не совпадает (порядок, время, какие-нибудь GUID), то сравнение с движком в этом случае ничего не доказывает.
Скорость стенд меряет так же аккуратно: штатная выгрузка и движок идут в одной серии на одной машине, не меньше трёх повторов строго по очереди, перед каждым запуском фиксируется свободная память.
Текущий счёт
| Этап | Результат |
|---|---|
| Первая версия выгрузки EPF | движок принял 4 файла из 208, все 4 совпали со штатной выгрузкой |
| Реквизиты и модуль объекта | 18 из 208 совпадают файл в файл, остальные 190 — честный отказ |
| Ошибок (выгрузил, но не то) | 0 |
18 из 208 — немного. Но для меня важнее последняя строка: движок ни разу не выдал неверный результат. Каждый отказ — это конкретное место в конкретном файле, то есть готовый список задач.
Что дальше
- Элементы форм. Это главная причина отказов на обработках: почти у всех есть формы с элементами.
- Внешние отчёты, затем расширения (CFE).
- Полная конфигурация из CF и формат выгрузки 2.21.
- Чтение напрямую из базы, без промежуточного CF.
На каждом шаге — тот же стенд и тот же критерий: файл в файл со штатной выгрузкой на всём корпусе, иначе отказ. Когда дойду до CF типовых конфигураций, будет вторая статья с таблицей «штатный против своего» по времени.
Если вы тоже разбирали внутренний формат 1С, расскажите в комментариях, на какие грабли наступили. Особенно интересно про различия между версиями платформы и про формы.
Вступайте в нашу телеграмм-группу Инфостарт
Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.