Как получить двоичные данные из строки в 1С на версиях платформы 8.3.8 и ниже

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

В современных версиях платформы «1С:Предприятие» (начиная с релиза 8.3.10) разработчикам доступен крайне удобный метод глобального контекста ПолучитьДвоичныеДанныеИзСтроки(). Этот метод позволяет за одну строку кода преобразовать любой текст в массив байтов с нужной кодировкой. Однако при поддержке старых конфигураций или работе на серверах с версией платформы 8.3.8 и ниже этот метод вызвать не удастся — его попросту не существует.

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

В чем заключается скрытая проблема при обычном преобразовании?

Казалось бы, решить задачу можно стандартной записью текста в поток или файл с последующим чтением. Но на практике внешние API и веб-сервисы (особенно принимающие формат JSON) часто отказываются обрабатывать полученные таким образом данные. Давайте проанализируем, почему это происходит:

  1. Проблема BOM (Byte Order Mark). При записи текста в кодировке UTF-8 встроенные механизмы 1С по умолчанию добавляют в начало файла три служебных байта (EF BB BF). Многие современные REST-сервисы не умеют корректно обрабатывать BOM и выдают ошибку разбора JSON.
  2. Удвоение символов перевода строки (CR/LF). При записи строк через стандартный метод ЗаписатьСтроку() платформа 1С автоматически добавляет в конец строки системный разделитель (в Windows это пара байтов 0D 0A, то есть Carriage Return и Line Feed). Если ваша исходная JSON-строка уже содержала переносы строк, то при сохранении они могут продублироваться, превратившись в искаженную последовательность 0D 0D 0A. При кодировании в Base64 это дает совершенно другой хэш, который принимающий сервер отвергает.

Ниже мы рассмотрим проверенные способы обхода этих ограничений.

Способ 1. Запись во временный файл с кодировкой "CESU-8" (Универсальный метод для 8.3.8)

Этот метод является наиболее надежным и кроссплатформенным для старых версий 1С. Чтобы обойти автоматическое добавление маркера BOM, мы применим небольшую хитрость — укажем кодировку "CESU-8". Для платформы 1С это фактически тот же самый UTF-8, но записываемый строго без BOM-символов в начале.

Также мы принудительно очистим параметр разделителя строк, передав пустую строку в конструктор объекта ЗаписьТекста.

Рассмотрим пошаговый пример реализации:


// Очистим исходный JSON от возможных лишних переносов строк, если это критично для сервиса
ИсходнаяСтрока = СодержимоеJSON; 

// Создаем временный файл на диске
ИмяВремФайла = ПолучитьИмяВременногоФайла("txt");

// Открываем файл для записи. 
// Параметры: ИмяФайла, Кодировка (CESU-8), РазделительСтрок (пусто), РазделительСтрокВФайле (пусто)
ЗаписьТекста = Новый ЗаписьТекста(ИмяВремФайла, "CESU-8", , , "");
ЗаписьТекста.Записать(ИсходнаяСтрока);
ЗаписьТекста.Закрыть();

// Считываем файл напрямую в объект ДвоичныеДанные
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВремФайла);

// Обязательно удаляем временный файл после использования
Попытка
    УдалитьФайлы(ИмяВремФайла);
Исключение
    // Обработка ошибки удаления файла при необходимости
КонецПопытки;

Этот код гарантирует, что на выходе вы получите чистые двоичные данные в формате UTF-8 без лишних байтов разметки и без BOM. Полученный объект ДвоичныеДанные можно смело кодировать в Base64 и отправлять в сервис. Для быстрой проверки отправки подготовленных данных и отладки REST API подойдёт инструмент для тестирования REST API в 1С.

Способ 2. Запись через ПотокВПамяти (Для платформы 8.3.9 и выше без файлов на диске)

Если вы работаете на платформе 8.3.9 или ваша конфигурация запущена на платформе 8.3.10+ в режиме совместимости с более старыми версиями, вы можете использовать работу с потоками в оперативной памяти. Это быстрее, так как не требует дисковых операций ввода-вывода.

Чтобы избежать искажения разделителей, мы будем использовать объект ЗаписьДанных вместо ЗаписьТекста, явно переопределив параметры пустых строк.

Проанализируем пример кода:


ПотокПамять = Новый ПотокВПамяти;

// Настраиваем ЗаписьДанных. 
// Задаем кодировку UTF-8 без BOM и передаем пустые строки вместо разделителей
Писатель = Новый ЗаписьДанных(ПотокПамять, КодировкаТекста.UTF8, , "", "");
Писатель.ЗаписатьСтроку(ИсходнаяСтрока, КодировкаТекста.UTF8);
Писатель.Закрыть();

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

Обратите внимание, что объект ПотокВПамяти недоступен на чистой платформе 8.3.8 (он появился только в версии 8.3.9). Если ваш сервер физически работает на релизе 8.3.8, используйте Способ 1.

Способ 3. Использование COM-объекта ADODB.Stream (Только для Windows-серверов)

Если ваше решение развернуто на операционной системе 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-объекты или конвертировать внешними библиотеками.

Обратное преобразование: Получение строки из Двоичных Данных в 1С 8.3.8

Для полноты картины рассмотрим обратный процесс, который часто требуется при получении ответа от веб-сервиса. Если вам нужно преобразовать пришедшие ДвоичныеДанные обратно в читаемую строку в условиях ограничений платформы 8.3.8, воспользуйтесь чтением через временный файл:


// Сохраняем полученные двоичные данные во временный файл
ИмяВремФайла = ПолучитьИмяВременногоФайла("txt");
ДвоичныеДанные.Записать(ИмяВремФайла);

// Считываем текст с явным указанием UTF-8 кодировки
ЧтениеТекста = Новый ЧтениеТекста(ИмяВремФайла, КодировкаТекста.UTF8);
РезультатСтрока = ЧтениеТекста.Прочитать();
ЧтениеТекста.Закрыть();

// Очищаем временные файлы
УдалитьФайлы(ИмяВремФайла);

Использование этого подхода гарантирует корректное распознавание кириллических символов и спецсимволов, исключая проблемы с несовместимостью кодировок при обмене данными. Для валидации и проверки структуры полученного JSON-ответа можно использовать инструмент для валидации и форматирования JSON в 1С.

← На главную