Как в 1С прочитать двоичный файл как строку (аналог file_get_contents в PHP) для HTTP-запроса

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

При интеграции 1С с внешними веб-сервисами разработчики часто сталкиваются со специфическими требованиями API. Одной из таких задач является передача содержимого двоичного файла (картинки, PDF-документа или архива) напрямую в теле или параметрах HTTP-запроса в виде строки, но без привычного кодирования в Base64. В языке PHP для этого существует простая функция file_get_contents(), которая читает файл «как есть» в бинарно-безопасную строку. В 1С задача осложняется тем, что платформа ориентирована на работу с типизированными ДвоичныеДанные или текстовыми строками в кодировке Unicode.

В этой статье мы разберем, как правильно прочитать нетекстовый файл в строковую переменную 1С, чтобы его содержимое не «рассыпалось» и могло быть корректно передано через протокол HTTP. Рассмотрим несколько способов решения, включая работу с объектами ТекстовыйДокумент и ЧтениеТекста, а также разберем нюансы кодировок.

Основная концепция: «Хакинг» с кодировкой ISO-8859-1

Главная проблема при чтении двоичного файла как текста заключается в том, что 1С пытается интерпретировать байты как символы определенной кодировки (обычно UTF-8). Если байт или последовательность байтов не соответствуют стандарту UTF-8, данные искажаются или заменяются на «символы-заполнители». Чтобы этого избежать, мы воспользуемся особенностью кодировки ISO-8859-1 (Latin-1).

В этой кодировке первые 256 символов таблицы соответствуют байтам от 0 до 255. Это позволяет нам «обмануть» систему: мы читаем файл как текст, и каждый байт двоичных данных превращается в ровно один символ строки 1С. Таким образом, структура файла сохраняется байт-в-байт.

Способ 1: Использование объекта ТекстовыйДокумент

Этот метод наиболее удобен, когда нам нужно быстро получить весь текст файла целиком и сразу подготовить его для отправки. Рассмотрим пример кода, который часто используется для интеграции с API (например, UniSender), где вложения передаются в параметрах запроса.


// Определяем пути к файлам
ПутьКФайлу = "C:\Files\document.pdf";

// Создаем объект для работы с текстом
Текст = Новый ТекстовыйДокумент;

// Читаем файл, принудительно указывая кодировку ISO-8859-1
// Важно использовать правильный разделитель строк, чтобы 1С не добавляла лишнего
Текст.Прочитать(ПутьКФайлу, "ISO-8859-1", Символы.ПС);

// Получаем содержимое в строковую переменную
СодержимоеСтрокой = Текст.ПолучитьТекст();

// Теперь строку нужно подготовить для передачи в URL или теле x-www-form-urlencoded
СтрокаДляЗапроса = КодироватьСтроку(СодержимоеСтрокой, СпособКодированияСтроки.КодировкаURL, "ISO-8859-1");

Проанализируем этот код: использование метода Прочитать с параметром "ISO-8859-1" гарантирует, что бинарные данные не будут преобразованы в Unicode с потерями. Метод КодироватьСтроку превратит спецсимволы в их шестнадцатеричное представление (например, %FF), что является стандартом для передачи данных в строке запроса.

Способ 2: Последовательное чтение через объект ЧтениеТекста

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


ПутьКФайлу = "C:\Files\image.jpg";

// Открываем файл для чтения в нужной кодировке
ФайлЧтения = Новый ЧтениеТекста(ПутьКФайлу, "ISO-8859-1");

// Читаем всё содержимое
// Можно читать частями в цикле: ФайлЧтения.Прочитать(КоличествоСимволов)
РезультатСтрока = ФайлЧтения.Прочитать();

ФайлЧтения.Закрыть();

// Пример формирования части HTTP-запроса
ПараметрВложения = "&attachments[image.jpg]=" + КодироватьСтроку(РезультатСтрока, СпособКодированияСтроки.КодировкаURL, "ISO-8859-1");

Выясним причину, по которой этот метод считается более «безопасным» для двоичных данных: ЧтениеТекста работает напрямую с потоком, и при правильном указании кодировки он минимально вмешивается в структуру данных. Однако стоит помнить, что 1С может реагировать на символы перевода строк. Если вы записываете результат обратно в файл для проверки, убедитесь, что не добавляются лишние CRLF.

Важные нюансы при отправке через HTTPЗапрос

Когда мы сформировали нашу «двоичную строку», ее нужно правильно передать на сервер, используя инструменты для тестирования REST API. Выясним, как не допустить повреждения данных при использовании объекта HTTPЗапрос.

1. Отключение Byte Order Mark (BOM). При установке тела запроса из строки 1С по умолчанию может добавить невидимый маркер в начало данных, что испортит файл для веб-сервера. Всегда используйте флаг ИспользованиеByteOrderMark.НеИспользовать.

2. Заголовки Content-Type. Если вы передаете данные в формате x-www-form-urlencoded, обязательно укажите соответствующий заголовок в Соответствие заголовков.


// Пример подготовки и отправки запроса
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");

// Сборка всей строки запроса (параметры + наше бинарное содержимое)
СтрокаТела = "api_key=your_key&subject=Test" + ПараметрВложения;

Запрос = Новый HTTPЗапрос("/api/send", Заголовки);
Запрос.УстановитьТелоИзСтроки(СтрокаТела, "UTF-8", ИспользованиеByteOrderMark.НеИспользовать);

// Отправка
Соединение = Новый HTTPСоединение("api.service.com", , , , , , Новый ЗащищенноеСоединениеOpenSSL());
Ответ = Соединение.ОтправитьДляОбработки(Запрос);

Почему нельзя просто использовать Base64?

Многие разработчики задаются вопросом: зачем такие сложности, если есть Base64Строка()? Проанализируем ситуацию: Base64 увеличивает размер передаваемых данных примерно на 33%. Однако в некоторых старых или узкоспециализированных API (как в примере из обсуждения) разработчики серверной части могут просто не реализовать поддержку декодирования Base64, ожидая данные в «сыром» виде или в формате url-encoded binary. В этом случае описанный выше метод с ISO-8859-1 является единственным рабочим способом в рамках платформы 1С.

Типичные ошибки и способы их решения

  1. Несовпадение контрольных сумм: Если файл доходит поврежденным, проверьте, не подменяет ли 1С символы конца строки. В методе Текст.Прочитать() третьим параметром следует явно указывать разделитель, используемый в файле, либо использовать объект ЧтениеДанных (в новых версиях платформы) для получения буфера.
  2. Ошибка 414 (Request-URI Too Long): Если вы пытаетесь передать большой файл (более 2-4 Кб) прямо в URL-строке (GET-запрос), сервер его обрежет. Всегда используйте POST и передавайте «бинарную строку» в теле запроса.
  3. Кодировка в КодироватьСтроку: Убедитесь, что в функции КодироватьСтроку третьим параметром также стоит "ISO-8859-1". Если оставить там "UTF-8", 1С попытается сначала конвертировать вашу бинарную строку в UTF-8, что безвозвратно испортит данные.

Рассмотренные нами приемы позволяют гибко работать с двоичными данными в среде, предназначенной для работы с текстом. Несмотря на то, что современные версии платформы 1С предлагают более продвинутые инструменты (например, БуферДвоичныхДанных), метод с кодировкой ISO-8859-1 остается классическим и надежным способом имитации поведения PHP-функции file_get_contents для интеграции с внешними системами.

← На главную