При интеграции через HTTP-сервисы или веб-сервисы разработчики часто получают входящие данные в виде объекта ДвоичныеДанные. Распространенной практикой долгое время было сохранение этих данных во временный файл через КаталогВременныхФайлов() с последующим чтением через ЧтениеXML. Однако дисковые операции ввода-вывода снижают производительность, создают лишнюю нагрузку на сервер и требуют очистки временных файлов.
Разберем способы преобразования двоичных данных в строку XML и последующего парсинга непосредственно в оперативной памяти, учитывая особенности различных версий платформы 1С:Предприятие.
Проанализируем работу с объектом ЧтениеДанных. При стандартном вызове метода Прочитать() возвращается объект РезультатЧтенияДанных, содержащий буфер байтов. Чтобы получить строковое представление, необходимо применить метод ПрочитатьСимволы(), указав нужную кодировку.
Посмотрим на пример чтения всей строки целиком:
// Создаем объект чтения данных с указанием кодировки входящего потока
Чтение = Новый ЧтениеДанных(вхДвДанные, КодировкаТекста.UTF8);
// Метод без параметров считывает все доступные символы до конца потока
СтрокаXML = Чтение.ПрочитатьСимволы();
Чтение.Закрыть();
// Передаем полученную строку в ЧтениеXML для дальнейшего разбора
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СтрокаXML);
Этот метод отлично подходит для работы на платформе 1С 8.3.9, где еще нет некоторых функций глобального контекста для прямой работы с бинарными строками.
Если используется платформа 1С версии 8.3.10 и выше, наиболее лаконичным решением будет вызов встроенной функции глобального контекста ПолучитьСтрокуИзДвоичныхДанных().
Рассмотрим синтаксис и пример использования:
// Преобразуем двоичные данные напрямую в строку
СтрокаXML = ПолучитьСтрокуИзДвоичныхДанных(вхДвДанные, КодировкаТекста.UTF8);
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СтрокаXML);
Важно: обязательно указывайте второй параметр с кодировкой (например, КодировкаТекста.UTF8 или КодировкаТекста.ANSI), чтобы избежать проблем с искажением кириллических символов при несовпадении системной кодировки по умолчанию.
Если входящие данные поступают в модуль HTTP-сервиса через объект HTTPСервисЗапрос, промежуточный шаг получения двоичных данных можно исключить. Платформа позволяет сразу получить тело запроса в виде строки.
Посмотрим, как оптимизировать обработчик HTTP-сервиса:
// Считываем тело запроса сразу в строку с явным указанием кодировки
СтрокаXML = Запрос.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
Если Не ПустаяСтрока(СтрокаXML) Тогда
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СтрокаXML);
// Дальнейшая логика обработки XML
КонецЕсли;
Для обработки больших XML-документов создание промежуточной строки в оперативной памяти может вызвать перерасход ресурсов. Начиная с версии 8.3.10, объект ЧтениеXML поддерживает метод ОткрытьПоток(), позволяющий парсить бинарные данные напрямую через потоки чтения.
Разберем по шагам реализацию потокового чтения:
ОткрытьПотокДляЧтения().ЧтениеXML и открываем в нем созданный поток.ФабрикаXDTO.ПрочитатьXML().Пример кода потоковой обработки:
Поток = вхДвДанные.ОткрытьПотокДляЧтения();
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьПоток(Поток);
// Выполняем чтение узлов или десериализацию XDTO
Пока ЧтениеXML.Прочитать() Цикл
// Обработка структуры XML
КонецЦикла;
ЧтениеXML.Закрыть();
Поток.Закрыть();
Если требуется обработать двоичные данные в памяти на старых версиях 1С (8.2 или ранние 8.3) в среде ОС Windows, можно воспользоваться объектом операционной системы ADODB.Stream.
Рассмотрим пример реализации:
Поток = Новый COMОбъект("ADODB.Stream");
Поток.Type = 1; // adTypeBinary
Поток.Open();
Поток.Write(вхДвДанные);
Поток.Position = 0;
Поток.Type = 2; // adTypeText
Поток.Charset = "utf-8";
СтрокаXML = Поток.ReadText();
Поток.Close();
Обратите внимание: данный способ работает исключительно под управлением Windows и неприменим на серверах под управлением Linux.