В современных версиях платформы «1С:Предприятие» (начиная с релиза 8.3.10) разработчикам доступен крайне удобный метод глобального контекста ПолучитьДвоичныеДанныеИзСтроки(). Этот метод позволяет за одну строку кода преобразовать любой текст в массив байтов с нужной кодировкой. Однако при поддержке старых конфигураций или работе на серверах с версией платформы 8.3.8 и ниже этот метод вызвать не удастся — его попросту не существует.
В этой статье мы подробно разберем, как решить эту задачу на старых релизах платформы, выясним причины типичных ошибок при работе со сторонними веб-сервисами и рассмотрим три практических способа получения двоичных данных без использования современных методов.
Казалось бы, решить задачу можно стандартной записью текста в поток или файл с последующим чтением. Но на практике внешние API и веб-сервисы (особенно принимающие формат JSON) часто отказываются обрабатывать полученные таким образом данные. Давайте проанализируем, почему это происходит:
EF BB BF). Многие современные REST-сервисы не умеют корректно обрабатывать BOM и выдают ошибку разбора JSON.ЗаписатьСтроку() платформа 1С автоматически добавляет в конец строки системный разделитель (в Windows это пара байтов 0D 0A, то есть Carriage Return и Line Feed). Если ваша исходная JSON-строка уже содержала переносы строк, то при сохранении они могут продублироваться, превратившись в искаженную последовательность 0D 0D 0A. При кодировании в Base64 это дает совершенно другой хэш, который принимающий сервер отвергает.Ниже мы рассмотрим проверенные способы обхода этих ограничений.
Этот метод является наиболее надежным и кроссплатформенным для старых версий 1С. Чтобы обойти автоматическое добавление маркера BOM, мы применим небольшую хитрость — укажем кодировку "CESU-8". Для платформы 1С это фактически тот же самый UTF-8, но записываемый строго без BOM-символов в начале.
Также мы принудительно очистим параметр разделителя строк, передав пустую строку в конструктор объекта ЗаписьТекста.
Рассмотрим пошаговый пример реализации:
// Очистим исходный JSON от возможных лишних переносов строк, если это критично для сервиса
ИсходнаяСтрока = СодержимоеJSON;
// Создаем временный файл на диске
ИмяВремФайла = ПолучитьИмяВременногоФайла("txt");
// Открываем файл для записи.
// Параметры: ИмяФайла, Кодировка (CESU-8), РазделительСтрок (пусто), РазделительСтрокВФайле (пусто)
ЗаписьТекста = Новый ЗаписьТекста(ИмяВремФайла, "CESU-8", , , "");
ЗаписьТекста.Записать(ИсходнаяСтрока);
ЗаписьТекста.Закрыть();
// Считываем файл напрямую в объект ДвоичныеДанные
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВремФайла);
// Обязательно удаляем временный файл после использования
Попытка
УдалитьФайлы(ИмяВремФайла);
Исключение
// Обработка ошибки удаления файла при необходимости
КонецПопытки;
Этот код гарантирует, что на выходе вы получите чистые двоичные данные в формате UTF-8 без лишних байтов разметки и без BOM. Полученный объект ДвоичныеДанные можно смело кодировать в Base64 и отправлять в сервис. Для быстрой проверки отправки подготовленных данных и отладки REST API подойдёт инструмент для тестирования REST API в 1С.
Если вы работаете на платформе 8.3.9 или ваша конфигурация запущена на платформе 8.3.10+ в режиме совместимости с более старыми версиями, вы можете использовать работу с потоками в оперативной памяти. Это быстрее, так как не требует дисковых операций ввода-вывода.
Чтобы избежать искажения разделителей, мы будем использовать объект ЗаписьДанных вместо ЗаписьТекста, явно переопределив параметры пустых строк.
Проанализируем пример кода:
ПотокПамять = Новый ПотокВПамяти;
// Настраиваем ЗаписьДанных.
// Задаем кодировку UTF-8 без BOM и передаем пустые строки вместо разделителей
Писатель = Новый ЗаписьДанных(ПотокПамять, КодировкаТекста.UTF8, , "", "");
Писатель.ЗаписатьСтроку(ИсходнаяСтрока, КодировкаТекста.UTF8);
Писатель.Закрыть();
// Извлекаем чистые двоичные данные
ДвоичныеДанные = ПотокПамять.ЗакрытьИПолучитьДвоичныеДанные();
Обратите внимание, что объект ПотокВПамяти недоступен на чистой платформе 8.3.8 (он появился только в версии 8.3.9). Если ваш сервер физически работает на релизе 8.3.8, используйте Способ 1.
Если ваше решение развернуто на операционной системе Windows и вы не хотите использовать временные файлы на жестком диске, можно прибегнуть к возможностям операционной системы через COM-соединение. Объект ADODB.Stream позволяет выполнять любые бинарные манипуляции со строками непосредственно в оперативной памяти.
Выполним преобразование следующим образом:
ПотокCOM = Новый COMОбъект("ADODB.Stream");
ПотокCOM.Type = 2; // Указываем текстовый тип потока
ПотокCOM.Charset = "utf-8";
ПотокCOM.Open();
ПотокCOM.WriteText(ИсходнаяСтрока);
// Переключаем поток в бинарный режим, чтобы пропустить BOM-маркер
ПотокCOM.Position = 0;
ПотокCOM.Type = 1; // Бинарный режим
ПотокCOM.Position = 3; // Пропускаем первые 3 байта (маркер UTF-8 BOM)
// Получаем массив байтов (SafeArray)
МассивБайтов = ПотокCOM.Read();
ПотокCOM.Close();
Полученный SafeArray можно передавать в другие COM-объекты или конвертировать внешними библиотеками.
Для полноты картины рассмотрим обратный процесс, который часто требуется при получении ответа от веб-сервиса. Если вам нужно преобразовать пришедшие ДвоичныеДанные обратно в читаемую строку в условиях ограничений платформы 8.3.8, воспользуйтесь чтением через временный файл:
// Сохраняем полученные двоичные данные во временный файл
ИмяВремФайла = ПолучитьИмяВременногоФайла("txt");
ДвоичныеДанные.Записать(ИмяВремФайла);
// Считываем текст с явным указанием UTF-8 кодировки
ЧтениеТекста = Новый ЧтениеТекста(ИмяВремФайла, КодировкаТекста.UTF8);
РезультатСтрока = ЧтениеТекста.Прочитать();
ЧтениеТекста.Закрыть();
// Очищаем временные файлы
УдалитьФайлы(ИмяВремФайла);
Использование этого подхода гарантирует корректное распознавание кириллических символов и спецсимволов, исключая проблемы с несовместимостью кодировок при обмене данными. Для валидации и проверки структуры полученного JSON-ответа можно использовать инструмент для валидации и форматирования JSON в 1С.