Разработка и Конфигурация · 12 мин
Как поместить файл в двоичные данные 1С
Как поместить файл в двоичные данные 1С: методы Новый ДвоичныеДанные, ПоместитьФайл, хранение в хранилище значения и передача через временное хранилище.
Двоичные данные в 1С — это универсальный тип, который позволяет работать с содержимым любого файла: картинки, PDF-документа, архива, XML или Excel. Файл считывается с диска в память как последовательность байтов, после чего его можно сохранить в базу данных, передать через веб-сервис, вложить в письмо или отдать пользователю на скачивание.
Типовая задача выглядит так: на сервере или клиенте есть файл, и его содержимое нужно получить в переменную типа ДвоичныеДанные. В зависимости от того, где выполняется код (тонкий клиент, веб-клиент, сервер, внешнее соединение), применяются разные механизмы: прямое чтение через конструктор, асинхронное помещение файла во временное хранилище или передача через параметры.
Ниже разобраны все рабочие способы с готовыми фрагментами кода, ограничениями каждого подхода и проверкой результата. Примеры ориентированы на управляемые формы и современный синтаксис платформы, но большинство приёмов работает и в обычных формах.
Что такое двоичные данные и когда они нужны
Тип ДвоичныеДанные представляет содержимое файла в виде набора байтов в оперативной памяти. Платформа не анализирует формат: для неё картинка, документ Word и архив выглядят одинаково. Интерпретация содержимого — задача прикладного кода или внешних программ.
Типичные сценарии использования: сохранение сканов документов и фотографий в справочниках, обмен файлами через HTTP-сервисы и веб-сервисы (там двоичные данные передаются напрямую или в Base64), формирование вложений электронных писем, выгрузка отчётов и печатных форм в файлы, передача данных между клиентом и сервером без промежуточных файлов на диске.
Важно понимать: двоичные данные живут в памяти сеанса и не сохраняются автоматически. Чтобы файл пережил завершение сеанса, его нужно записать на диск методом Записать(), поместить в реквизит типа ХранилищеЗначения или в реквизит с типом ДвоичныеДанные (у некоторых объектов, например у констант, такой тип доступен с ограничениями).
Способ 1. Чтение файла на сервере через конструктор
Самый короткий путь, когда файл физически доступен с того компьютера, где выполняется код (обычно это сервер 1С или файловая база на локальной машине):
ДвоичныеДанные = Новый ДвоичныеДанные("C:\Docs\scans\act.pdf");
Конструктор принимает полный путь к файлу и загружает его целиком в память. Если файл не существует или нет прав на чтение, платформа вызовет исключение, поэтому в прикладном коде чтение стоит оборачивать в попытку:
Попытка
ДД = Новый ДвоичныеДанные(ПутьКФайлу);
Исключение
Сообщить("Не удалось прочитать файл: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Обратная операция — сохранение двоичных данных в файл — выполняется методом Записать:
ДД.Записать("C:\Temp\copy_act.pdf");
Способ 2. Помещение файла с клиента через временное хранилище
В клиент-серверном режиме сервер не видит диск пользователя, поэтому файл сначала передаётся с клиента во временное хранилище, а уже оттуда серверный код забирает двоичные данные. В управляемых формах для этого служит метод НачатьПомещениеФайла (асинхронный) или ПоместитьФайл (синхронный, доступен не везде).
Асинхронное помещение с выбором файла
&НаКлиенте
Процедура ВыбратьФайл(Команда)
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект);
НачатьПомещениеФайла(ОписаниеОповещения, , , Истина, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, Адрес, ВыбранноеИмяФайла, ДопПараметры) Экспорт
Если Результат Тогда
СохранитьНаСервере(Адрес);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура СохранитьНаСервере(Адрес)
ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
// дальше: запись в хранилище значения, на диск и т.д.
КонецПроцедуры
Четвёртый параметр Истина включает интерактивный режим — пользователю будет показан диалог выбора файла. Если путь уже известен (например, файл лежит по фиксированному адресу на клиентской машине), диалог можно не показывать и передать имя файла вторым параметром.
Помещение без диалога
Когда имя файла известно заранее:
НачатьПомещениеФайла(Оповещение, , "C:\Temp\data.xml", Ложь, УникальныйИдентификатор);
Способ 3. Сохранение двоичных данных в базу данных
Полученные двоичные данные чаще всего сохраняют в реквизит типа ХранилищеЗначения — он есть у справочников, документов, регистров сведений. Хранилище значения сериализует объект и компактно держит его в базе.
&НаСервере
Процедура СохранитьФайлВЭлемент(Адрес, ЭлементСсылка)
ДД = ПолучитьИзВременногоХранилища(Адрес);
Элемент = ЭлементСсылка.ПолучитьОбъект();
Элемент.ДанныеФайла = Новый ХранилищеЗначения(ДД, Новый СжатиеДанных(9));
Элемент.Записать();
КонецПроцедуры
Чтение выполняется в обратном порядке: из реквизита вызывается метод Получить(), который возвращает исходные двоичные данные. Сжатие при сохранении уменьшает объём базы, но не имеет смысла для уже сжатых форматов (jpg, zip, mp4) — там оно лишь тратит процессорное время.
В типовых конфигурациях файлы обычно хранятся не в самом объекте-владельце, а в присоединённых файлах (справочник вида «ХранилищеФайлов» или регистр сведений «ДвоичныеДанныеФайлов»). Это позволяет версионировать файлы и не раздувать основные таблицы. Перед тем как писать свой механизм, проверьте, нет ли в конфигурации готовой подсистемы работы с файлами.
Способ 4. Помещение двоичных данных во временное хранилище для передачи клиенту
Обратная задача: двоичные данные сформированы или прочитаны на сервере, и их нужно отдать на клиент — например, чтобы показать картинку или сохранить файл у пользователя. Для этого служит ПоместитьВоВременноеХранилище:
&НаСервере
Функция ПодготовитьФайл()
ДД = Новый ДвоичныеДанные(ПутьНаСервере);
Возврат ПоместитьВоВременноеХранилище(ДД, УникальныйИдентификатор);
КонецФункции
&НаКлиенте
Процедура Скачать(Команда)
Адрес = ПодготовитьФайл();
ПолучитьФайл(Адрес, "report.pdf", Истина);
КонецПроцедуры
Адрес временного хранилища также используется в реквизитах формы типа Строка для элементов «Поле картинки»: достаточно присвоить адрес реквизиту, связанному с полем, и платформа отобразит изображение без записи файла на диск клиента.
Конвертация в Base64 и обратно
При обмене через HTTP-запросы, JSON или XML двоичные данные нельзя передать «как есть» в текстовом теле — их кодируют в Base64. Платформа умеет это штатно:
// Двоичные данные -> строка Base64
Строка64 = Base64Строка(ДвоичныеДанные);
// Строка Base64 -> двоичные данные
ДД = Base64Значение(Строка64);
В веб-сервисах 1С тип ДвоичныеДанные автоматически сериализуется в Base64 при передаче через SOAP, поэтому там ручное кодирование обычно не требуется. А вот при ручной сборке JSON через ЗаписьJSON про Base64 нужно позаботиться самостоятельно.
Сравнение способов
Самый простой вариант, но работает только там, где файл физически доступен исполняющему коду — на сервере или в файловой базе.
Стандартный путь для тонкого и веб-клиента. Требует асинхронного кода и расширения работы с файлами.
Для постоянного хранения в базе. Увеличивает размер базы, при больших объёмах лучше выносить файлы в отдельные таблицы или тома.
Для обмена через текстовые форматы и HTTP. Увеличивает объём данных примерно на треть.
Проверка результата и типичные ошибки
После помещения файла убедитесь, что данные реально получены. Простейшая проверка — размер: у двоичных данных есть метод Размер(), возвращающий количество байт. Нулевой размер или исключение при чтении — признак того, что файл не был помещён.
ДД = ПолучитьИзВременногоХранилища(Адрес);
Если ТипЗнч(ДД) <> Тип("ДвоичныеДанные") Или ДД.Размер() = 0 Тогда
Сообщить("Файл не получен или пуст");
КонецЕсли;
Как проверить результат
ТипЗнч возвращает ДвоичныеДанные
Неопределено или Строка — данные не помещены или получен адрес вместо содержимого
Размер() больше нуля и совпадает с размером исходного файла
0 байт или сильное расхождение с размером файла на диске
После ДД.Записать(путь) файл открывается штатной программой
Файл создаётся, но не открывается — вероятно, повреждена кодировка или записан Base64-текст
Ограничения и рекомендации по безопасности
Двоичные данные — частый канал проникновения вредоносного содержимого. Если файлы загружают пользователи, ограничивайте допустимые расширения и максимальный размер на уровне кода, а не только в диалоге выбора: фильтр диалога пользователь может обойти. Также не используйте имя файла, полученное от клиента, для записи на диск сервера без очистки — в нём могут быть пути вида «../../».
По производительности: временное хранилище, привязанное к форме (с передачей УникальныйИдентификатор), очищается при закрытии формы, а хранилище без привязки живёт до конца сеанса. При массовой загрузке файлов явно удаляйте ненужные данные через УдалитьИзВременногоХранилища, чтобы не раздувать память сервера.
Что важно запомнить
На сервере файл читается конструктором Новый ДвоичныеДанные(путь), с клиента — через НачатьПомещениеФайла во временное хранилище с последующим ПолучитьИзВременногоХранилища на сервере. Для постоянного хранения используйте ХранилищеЗначения, для текстового обмена — Base64. Всегда проверяйте тип и размер полученных данных и ограничивайте загружаемые файлы.
Частые вопросы
Можно ли поместить файл в двоичные данные без временного хранилища на клиенте?
Да, в толстом клиенте и в файловой базе конструктор Новый ДвоичныеДанные доступен и на клиенте — файл читается напрямую. В тонком и веб-клиенте этот конструктор недоступен, поэтому там единственный штатный путь — помещение во временное хранилище.
Как узнать размер двоичных данных?
У объекта есть метод Размер(), возвращающий число байт. Его удобно использовать для проверки, что файл загрузился, и для контроля лимитов перед сохранением в базу.
Чем двоичные данные отличаются от хранилища значения?
Двоичные данные — сам объект с байтами в памяти. Хранилище значения — обёртка, которая умеет сериализовать любое значение (в том числе двоичные данные) для записи в реквизит базы. В базу напрямую двоичные данные кладутся только в специальные реквизиты, чаще используют именно хранилище значения.
Почему ПолучитьИзВременногоХранилища возвращает Неопределено?
Адрес недействителен: данные уже удалены, форма, к которой привязано хранилище, закрыта, или на сервер передан пустой/чужой адрес. Проверьте, что при помещении файла обработчик получил Результат = Истина и что адрес передаётся в тот же сеанс.
Как передать двоичные данные через HTTP-запрос?
Объект двоичных данных можно установить как тело запроса методом УстановитьТелоИзДвоичныхДанных у объекта HTTPЗапрос — так файл передаётся без кодирования. Если API принимает JSON, данные предварительно кодируют функцией Base64Строка.
Есть ли ограничение на размер файла?
Жёсткого платформенного лимита нет, но практический предел задаётся доступной памятью сервера или клиента: файл загружается целиком. Дополнительно ограничения могут накладывать веб-сервер (для веб-клиента) и настройки кластера. Для очень больших файлов используйте файловые потоки с чтением по частям.