Файлы и обмен данными в 1С

Двоичные данные в 1С: как записать в файл, получить и преобразовать

Коротко

Чтобы выгрузить двоичные данные в файл, вызовите у объекта ДвоичныеДанные метод Записать(), передав путь к файлу или поток. Обратная операция — конструктор Новый ДвоичныеДанные(ИмяФайла), который читает файл целиком в память. Для преобразований используйте Base64Строка() / Base64Значение() и пару ПолучитьСтрокуИзДвоичныхДанных() / ПолучитьДвоичныеДанныеИзСтроки(), а для хранения в реквизите — тип ХранилищеЗначения.

Главные грабли — клиент-серверный контекст: конструктор и Записать() недоступны в веб-клиенте, а ХранилищеЗначения.Получить() работает только на сервере и в толстом клиенте.

Как получить двоичные данные из файла: Новый ДвоичныеДанные

Базовый способ получить двоичные данные в 1С из файла — конструктор Новый ДвоичныеДанные. Он читает файл целиком и возвращает неизменяемый объект, который можно передавать между клиентом и сервером, класть в HTTP-запрос или в ХранилищеЗначения:

Данные = Новый ДвоичныеДанные("C:\Temp\report.pdf");
Сообщить("Размер: " + Данные.Размер() + " байт");
Новый ДвоичныеДанные
ИмяФайлапуть к файлу, из которого читаются данные
ДвоичныеДанные

Важно: в веб-клиенте конструктор недоступен — там используется асинхронный метод глобального контекста НачатьСозданиеДвоичныхДанныхИзФайла() либо функция ПолучитьДвоичныеДанныеФайла() (см. ниже). На сервере ограничений нет, но файл должен быть доступен именно серверу, а не машине пользователя.

Как записать двоичные данные в файл в 1С: метод Записать()

Метод Записать() объекта ДвоичныеДанные выгружает содержимое в файл или в открытый поток. Типовой сценарий — достали данные из базы или из HTTP-ответа и сохраняете на диск:

// Ответ внешнего сервиса → файл на сервере
Ответ = Соединение.Получить(Запрос);
Данные = Ответ.ПолучитьТелоКакДвоичныеДанные();
Данные.Записать(ИмяВременногоФайла);

Метод доступен в тонком и толстом клиенте, на сервере и во внешнем соединении, но не в веб-клиенте. Для интерактивных сценариев в актуальных версиях платформы есть асинхронный вариант:

&НаКлиенте
Асинх Процедура СохранитьВложение(Данные, ИмяФайла)
    Ждать Данные.ЗаписатьАсинх(ИмяФайла);
КонецПроцедуры
ЗаписатьАсинх
ИмяФайлапуть к файлу-приёмнику на клиенте
Обещание

Записывать файл на клиентской машине лучше во временный каталог или через диалог выбора файла: жёстко зашитые пути вроде C:\Temp ломаются на первом же компьютере без такого каталога.

ПолучитьДвоичныеДанныеФайла: чтение файла на клиенте

В свежих версиях платформы (8.3.15+) в глобальном контексте появилась функция ПолучитьДвоичныеДанныеФайла() — она читает файл в тонком клиенте без объявления синхронных вызовов и имеет асинхронного близнеца для веб-клиента:

// Тонкий клиент
Данные = ПолучитьДвоичныеДанныеФайла(ПутьКФайлу);

// Веб-клиент / универсальный асинхронный код
Данные = Ждать ПолучитьДвоичныеДанныеФайлаАсинх(ПутьКФайлу);

Дальше данные обычно уезжают на сервер. Не передавайте большие ДвоичныеДанные параметром серверной процедуры — используйте временное хранилище: на клиенте ПоместитьВоВременноеХранилище(Данные) возвращает адрес-строку, а на сервере ПолучитьИзВременногоХранилища(Адрес) отдаёт данные обратно.

В Консоли кода такой цепочки не нужно: агент выполняет код сразу на сервере. Достаточно попросить «прочитай файл из каталога обмена и покажи первые байты» — агент сам напишет и выполнит фрагмент с Новый ДвоичныеДанные.

1С: двоичные данные в строку и обратно

Начиная с 8.3.10 платформа умеет напрямую конвертировать: в 1С двоичные данные в строку превращает ПолучитьСтрокуИзДвоичныхДанных(), обратно — ПолучитьДвоичныеДанныеИзСтроки(). До этого приходилось писать текст во временный файл и читать его ЧтениеТекста.

// Двоичные данные → строка (данные должны быть текстом!)
Текст = ПолучитьСтрокуИзДвоичныхДанных(Данные, КодировкаТекста.UTF8);

// Строка → двоичные данные
Данные = ПолучитьДвоичныеДанныеИзСтроки(Текст, КодировкаТекста.UTF8, Ложь);

Ключевое ограничение: эти функции — про текстовое содержимое (JSON, XML, CSV внутри двоичных данных). Прогонять через них PDF или картинку нельзя — байты, не являющиеся валидным текстом в выбранной кодировке, будут искажены. Для произвольных байтов используйте Base64. Третий параметр ПолучитьДвоичныеДанныеИзСтроки() управляет добавлением BOM — для обмена с внешними системами обычно передают Ложь.

Двоичные данные в Base64: Base64Строка и Base64Значение

Стандартный способ передать бинарный файл в JSON или XML — перевести 1С двоичные данные в Base64 функцией Base64Строка(); разбор входящей строки делает Base64Значение():

Строка64 = Base64Строка(Данные);
// Base64Строка вставляет переводы строк каждые 64 символа —
// большинство API ждёт монолитную строку:
Строка64 = СтрЗаменить(Строка64, Символы.ПС, "");
Строка64 = СтрЗаменить(Строка64, Символы.ВК, "");

// Обратно: строка Base64 → ДвоичныеДанные
Данные = Base64Значение(Строка64);
Данные.Записать(ИмяФайла);

Помните про накладные расходы: Base64 раздувает объём примерно на треть, поэтому для файлов в десятки мегабайт лучше отдавать тело запроса напрямую через УстановитьТелоИзДвоичныхДанных(), а Base64 оставить для случаев, когда данные должны лежать внутри JSON-поля.

Хранилище двоичных данных 1С: ХранилищеЗначения в реквизите

Чтобы файл жил внутри базы, в объекте метаданных создают реквизит с типом ХранилищеЗначения. Это и есть типовое хранилище двоичных данных 1С: значение упаковывается (опционально сжимается) при записи и распаковывается методом Получить():

// Положить файл в реквизит справочника
Данные = Новый ДвоичныеДанные(ИмяФайла);
Объект = СсылкаНаЭлемент.ПолучитьОбъект();
Объект.ДанныеФайла = Новый ХранилищеЗначения(Данные, Новый СжатиеДанных(9));
Объект.Записать();

// Достать обратно и выгрузить в файл
Данные = СсылкаНаЭлемент.ДанныеФайла.Получить();
Данные.Записать(ИмяФайлаКопии);
Новый ХранилищеЗначения
Значениесохраняемое значение, например ДвоичныеДанные
АлгоритмСжатияДанныхобъект СжатиеДанных с уровнем 0–9
ХранилищеЗначения

Метод Получить() возвращает Произвольный и доступен только на сервере, в толстом клиенте и внешнем соединении — в клиентском коде управляемой формы распаковать хранилище нельзя, данные готовят на сервере. Ещё нюанс: не выбирайте реквизит-хранилище в запросах динамических списков — каждая строка потянет за собой мегабайты из СУБД.

Получить двоичные данные вложения: ПрисоединенныеФайлы

В конфигурациях на БСП файлы-вложения лежат не в реквизите владельца, а в подчинённых справочниках вида <Владелец>ПрисоединенныеФайлы (данные — в томах на диске или в специальном регистре). Получить двоичные данные вложения руками через реквизиты не выйдет — используйте программный интерфейс БСП:

// Сервер. БСП 3.x: универсальное получение данных вложения
Данные = РаботаСФайлами.ДвоичныеДанныеФайла(СсылкаНаВложение);

// Все вложения объекта
Вложения = РаботаСФайлами.ПрисоединенныеФайлы(СсылкаНаДокумент);
Для Каждого Вложение Из Вложения Цикл
    Данные = РаботаСФайлами.ДвоичныеДанныеФайла(Вложение);
    Данные.Записать(КаталогВыгрузки + Вложение.Наименование + "." + Вложение.Расширение);
КонецЦикла;

Имена модулей зависят от версии БСП: в старых релизах те же операции живут в общем модуле ПрисоединенныеФайлы. Ориентируйтесь на программный интерфейс своей конфигурации, а не на прямое чтение регистров — структура хранения считается внутренней и меняется между версиями.

Типовая связка «достать вложение — перегнать в Base64 — отправить POST во внешний сервис» — задача на один запрос к агенту Консоли кода: он найдёт справочник вложений вашей конфигурации, получит данные и соберёт HTTP-запрос, показав результат до записи куда-либо.

Большие файлы: потоки вместо чтения в память

Новый ДвоичныеДанные загружает файл в память целиком — для гигабайтных выгрузок это заканчивается исчерпанием памяти рабочего процесса. Работайте блочно через потоки: у объекта ДвоичныеДанные есть метод ОткрытьПотокДляЧтения(), а читать файл с диска по частям можно ФайловыйПоток в связке с БуферДвоичныхДанных:

Поток = Данные.ОткрытьПотокДляЧтения();
Буфер = Новый БуферДвоичныхДанных(1024 * 1024); // блок 1 МБ
Прочитано = Поток.Прочитать(Буфер, 0, Буфер.Размер);
Пока Прочитано > 0 Цикл
    // обработка блока
    Прочитано = Поток.Прочитать(Буфер, 0, Буфер.Размер);
КонецЦикла;
Поток.Закрыть();

Тот же приём спасает при проксировании больших файлов между хранилищем и HTTP-сервисом: данные не материализуются в памяти одним куском.

Частые ошибки при работе с двоичными данными в 1С

  • Вызов Новый ДвоичныеДанные или Записать() в веб-клиенте. Оба недоступны — используйте НачатьСозданиеДвоичныхДанныхИзФайла(), ПолучитьДвоичныеДанныеФайлаАсинх() и ЗаписатьАсинх().
  • Чтение клиентского файла серверным кодом. Путь C:\Users\... существует на машине пользователя, а конструктор выполняется на сервере. Файл сначала передают через временное хранилище.
  • ПолучитьСтрокуИзДвоичныхДанных() для PDF или картинки. Функция предназначена для текстового содержимого; произвольные байты после «строки» назад не восстановятся. Бинарные данные — только через Base64 или потоки.
  • Base64 с переводами строк. Base64Строка() режет вывод на строки по 64 символа — внешние API часто отвечают ошибкой валидации. Чистите Символы.ПС и Символы.ВК.
  • ХранилищеЗначения.Получить() на клиенте. Метод доступен на сервере, в толстом клиенте и внешнем соединении. В управляемой форме данные распаковывает серверная процедура.
  • Гигабайтные файлы одним объектом. Чтение целиком в ДвоичныеДанные и упаковка в ХранилищеЗначения раздувают память и базу. Используйте потоки и тома/внешние хранилища.

Частые вопросы о двоичных данных в 1С

Как передать двоичные данные с клиента на сервер?

Через временное хранилище: на клиенте ПоместитьВоВременноеХранилище(Данные, УникальныйИдентификатор) возвращает адрес-строку, её передают в серверную процедуру, где ПолучитьИзВременногоХранилища(Адрес) отдаёт данные. Передача самих ДвоичныеДанные параметром допустима для мелких файлов, но на больших объёмах упирается в память и тайм-ауты.

Чем ХранилищеЗначения отличается от хранения файла на диске?

ХранилищеЗначения держит данные внутри базы: они попадают в бэкап и переносятся вместе с объектом, но раздувают СУБД и замедляют реструктуризацию. Файлы на диске (тома БСП, каталоги обмена) экономят базу, зато требуют отдельного резервного копирования и контроля прав на каталоги.

Как получить строку Base64 без переводов строк?

Вызвать Base64Строка(Данные) и убрать разделители: СтрЗаменить(Строка64, Символы.ПС, "") и аналогично для Символы.ВК. Обратное преобразование Base64Значение() одинаково принимает строку и с переводами строк, и без них.

Тарифы

ИИ Консоль кода 1С

Лайт

Бесплатно
≈ 1,5 млн токенов

Для ознакомления с возможностями

  • Все функции бесплатно на 2 дня +2 дня за подписку на Telegram или Max
  • Полный набор инструментов без урезаний
  • Без ввода карты
Начать бесплатно

Старт

1990 руб. в месяц
≈ 10 млн токенов

Для индивидуального использования

Выбрать тариф

Продвинутый

Популярный выбор
3990 руб. в месяц
≈ 25 млн токенов

Для интенсивного использования или команд

  • До 15 конфигураций
  • Встроенный агент запросов 1С
  • Свои подписки Codex, Claude и любые OpenAI-совместимые
  • Внешние обработки без Конфигуратора
  • Приоритетная техническая поддержка
Выбрать тариф