К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как получить двоичные данные файла в 1С

Как получить двоичные данные файла в 1С: конструктор ДвоичныеДанные, чтение с диска, из хранилища значений, временного хранилища. Примеры кода и ошибки.

Двоичные данные в 1С — это универсальный способ представить содержимое любого файла (картинки, PDF, архива, Excel-документа) в виде объекта, с которым можно работать программно: сохранить в базу, передать через веб-сервис, отправить по HTTP или записать в другое место. Тип ДвоичныеДанные доступен и на толстом, и на тонком, и на веб-клиенте, что делает его стандартным инструментом обмена файлами между клиентом и сервером.

Способов получить двоичные данные несколько: напрямую из файла на диске, из хранилища значения реквизита объекта, из временного хранилища после интерактивного выбора файла пользователем, из потока в памяти. Выбор зависит от того, где файл находится и на какой стороне (клиент или сервер) выполняется код.

Ниже разобраны рабочие примеры кода, ограничения платформы, типичные ошибки вроде перепутанных контекстов выполнения и способы проверить, что данные получены корректно.

Что такое тип ДвоичныеДанные и когда он нужен

Объект типа ДвоичныеДанные хранит содержимое файла в виде последовательности байт. Платформа не анализирует внутренний формат — для неё это просто массив байт заданного размера. У объекта есть методы Записать() для сохранения в файл и Размер() для получения длины в байтах.

Типичные сценарии использования: сохранение вложений в реквизит типа ХранилищеЗначения, передача файлов в HTTP-сервисы и веб-сервисы, формирование пакетов обмена, работа с криптографией и подписанием, чтение картинок для вывода в формы и печатные формы.

Получение двоичных данных из файла на диске

Базовый способ — конструктор с указанием полного пути к файлу. Код выполняется там, где физически доступен файл: если путь указывает на диск сервера, код должен выполняться на сервере.

ДвоичныеДанныеФайла = Новый ДвоичныеДанные("C:\Обмен\order.xml");

РазмерФайла = ДвоичныеДанныеФайла.Размер(); // размер в байтах

Если файла не существует или нет прав на чтение, платформа вызовет исключение. Поэтому перед чтением полезно проверить существование файла:

ФайлНаДиске = Новый Файл("C:\Обмен\order.xml");

Если ФайлНаДиске.Существует() Тогда

ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ФайлНаДиске.ПолноеИмя);

Иначе

ВызватьИсключение "Файл не найден: " + ФайлНаДиске.ПолноеИмя;

КонецЕсли;

Получение файла от пользователя на клиенте

В управляемом приложении прямой доступ клиента к диску ограничен, а сервер не видит диск пользователя. Стандартная схема — асинхронное помещение файла во временное хранилище с последующей обработкой на сервере.

Интерактивный выбор через диалог

&НаКлиенте

Процедура ВыбратьФайл(Команда)

ОписаниеОповещения = Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект);

НачатьПомещениеФайла(ОписаниеОповещения, , , Истина, УникальныйИдентификаторФормы);

КонецПроцедуры

&НаКлиенте

Процедура ПослеПомещенияФайла(Результат, Адрес, ВыбранноеИмяФайла, ДопПараметры) Экспорт

Если Результат Тогда

АдресХранилища = Адрес; // реквизит формы

ЗагрузитьНаСервере(АдресХранилища);

КонецЕсли;

КонецПроцедуры

После помещения файл доступен на сервере по адресу временного хранилища. Извлечение выполняется методом ПолучитьИзВременногоХранилища, который возвращает именно объект ДвоичныеДанные.

&НаСервере

Процедура ЗагрузитьНаСервере(Адрес)

ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(Адрес);

// дальше: сохранить в реквизит, распаковать, записать на диск сервера

КонецПроцедуры

Порядок действий при загрузке с клиента
  1. 1
    Вызовите НачатьПомещениеФайла с описанием оповещения и УникальныйИдентификатор формы
  2. 2
    В обработчике оповещения проверьте Результат и сохраните адрес временного хранилища
  3. 3
    Передайте адрес в серверную процедуру
  4. 4
    На сервере вызовите ПолучитьИзВременногоХранилища(Адрес) — получите ДвоичныеДанные
  5. 5
    Проверьте Размер() результата и сохраните данные в реквизит или файл

Получение двоичных данных из хранилища значения

Вложения в базе обычно хранятся в реквизитах типа ХранилищеЗначения. Чтобы получить двоичные данные, нужно вызвать метод Получить() у значения реквизита:

Запрос = Новый Запрос("ВЫБРАТЬ Файл ИЗ Справочник.ПрисоединенныеФайлы ГДЕ Ссылка = &Ссылка");

Запрос.УстановитьПараметр("Ссылка", ФайлСсылка);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

ДвоичныеДанныеФайла = Выборка.Файл.Получить();

Если ТипЗнч(ДвоичныеДанныеФайла) = Тип("ДвоичныеДанные") Тогда

ДвоичныеДанныеФайла.Записать("C:\Temp\выгрузка.pdf");

КонецЕсли;

КонецЕсли;

Важно проверять тип результата: Получить() может вернуть Неопределено, если хранилище пустое, или объект другого типа, если в хранилище помещали не двоичные данные. Обращение к методам несуществующего объекта приведёт к ошибке выполнения.

Получение из потока и Base64

Если данные приходят не файлом, а по сети, удобнее работать с потоками. Метод ПолучитьДвоичныеДанные() объекта Поток считывает всё содержимое:

Поток = ФайловыеПотоки.ОткрытьДляЧтения("C:\Обмен\data.zip");

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

Поток.Закрыть();

При обмене через HTTP-API файлы часто передаются в формате Base64. Платформа предоставляет функции Base64Значение() для декодирования строки в двоичные данные и Base64Строка() для обратного преобразования:

ДвоичныеДанныеФайла = Base64Значение(СтрокаBase64ИзJSON);

СтрокаДляОтправки = Base64Строка(ДвоичныеДанныеФайла);

Сравнение способов получения двоичных данных

СпособИсточник файлаГде выполняетсяОграничение
Новый ДвоичныеДанные(Путь)Файл на дискеКлиент или серверФайл должен быть доступен с машины выполнения
НачатьПомещениеФайла + временное хранилищеДиск пользователяКлиент → серверДанные живут до закрытия формы или удаления
ХранилищеЗначения.Получить()Реквизит объекта БДСерверМожет вернуть Неопределено или другой тип
Поток.ПолучитьДвоичныеДанные()Поток в памяти / файловый потокКлиент или серверТребует закрытия потока
Base64Значение()Строка из JSON/XMLКлиент или серверОшибка при повреждённой строке

Что выбрать

Новый ДвоичныеДанные(Путь)

Подходит для регламентных заданий и серверной обработки, когда файл уже лежит в каталоге обмена. Не работает с диском клиента из серверного кода.

Временное хранилище

Единственный корректный путь, когда файл выбирает пользователь в управляемой форме. Требует передачи адреса между клиентом и сервером.

Хранилище значения

Для файлов, уже сохранённых в базе. Перед использованием проверяйте тип результата метода Получить().

Проверка результата и типичные ошибки

После получения двоичных данных убедитесь, что они не пустые и соответствуют ожидаемому файлу. Минимальная проверка — размер: нулевой размер почти всегда означает, что файл не был прочитан или хранилище пустое. Для известных форматов можно дополнительно проверить первые байты (сигнатуру): PDF начинается с %PDF, ZIP-архивы и документы Office — с PK.

Контрольные точки

Как проверить результат

Размер данных
Норма

Размер() больше нуля и совпадает с размером исходного файла

Тревожный признак

Размер равен 0 — файл не прочитан или хранилище пустое

Тип значения из хранилища
Норма

ТипЗнч(Результат) = Тип("ДвоичныеДанные")

Тревожный признак

Неопределено или другой тип — в реквизите лежит не файл

Запись обратно в файл
Норма

Файл создаётся и открывается штатной программой

Тревожный признак

Файл создаётся, но не открывается — данные повреждены или перепутана кодировка Base64

Типичные ошибки
01
Чтение файла с диска клиента в серверной процедуре — ошибка доступа, файл не найден; используйте временное хранилище
02
Отсутствие проверки результата ХранилищеЗначения.Получить() — падение на пустых реквизитах
03
Использование устаревшего ПоместитьФайл в модальном режиме — блокируется в веб-клиенте и новых версиях платформы
04
Забытый УникальныйИдентификатор формы при помещении — адрес хранилища теряется после закрытия формы или обновления
05
Передача двоичных данных между вызовами сервера напрямую вместо адреса хранилища — лишний трафик и риск потери данных

Отдельная группа проблем — большие файлы. Загрузка файла целиком в память при обмене по HTTP может приводить к существенному расходу оперативной памяти и тайм-аутам. Для объёмных данных рассмотрите передачу частями через потоки или файловый обмен через общий каталог, а не прямое помещение в тело запроса.

Часто задаваемые вопросы

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

Прочитайте реквизит типа ХранилищеЗначения через запрос или объектную модель и вызовите у него метод Получить(). Результат и будет объектом ДвоичныеДанные, который можно записать в файл или поместить во временное хранилище для показа в форме.

Можно ли получить двоичные данные файла без сохранения на диск?

Да. Если данные уже в памяти (например, получены по HTTP или сформированы программно), используйте потоки: запишите данные в ПотокВПамяти и вызовите ПолучитьДвоичныеДанные(). Промежуточный файл на диске не требуется.

Почему ПолучитьИзВременногоХранилища возвращает Неопределено?

Чаще всего адрес указывает на уже очищенное хранилище: форма закрыта, данные удалены явно или адрес получен без привязки к УникальныйИдентификатор формы и потерян. Проверьте, что адрес актуален и передаётся в ту же сессию.

Чем ДвоичныеДанные отличаются от ХранилищаЗначения?

ДвоичныеДанные — само содержимое файла в байтах. ХранилищеЗначения — обёртка для сохранения произвольного значения (в том числе двоичных данных) в реквизите базы со сжатием. Чтобы получить данные из хранилища, вызывают метод Получить().

Как передать двоичные данные с клиента на сервер без временного хранилища?

Для небольших данных можно закодировать их в Base64 функцией Base64Строка() на клиенте и передать строку параметром в серверную процедуру, где декодировать через Base64Значение(). Для файлов заметного размера этот способ неэффективен — лучше временное хранилище.

Работает ли Новый ДвоичныеДанные в веб-клиенте?

Конструктор доступен, но прямое чтение произвольного файла с диска в веб-клиенте ограничено браузерной безопасностью. Практический путь — НачатьПомещениеФайла с диалогом выбора, который работает в веб-клиенте штатно.

Итог

Что важно запомнить

Файл с диска читается конструктором Новый ДвоичныеДанные(Путь) на той стороне, где файл физически доступен. Файл пользователя передаётся на сервер через временное хранилище, из реквизита базы данные извлекаются методом Получить(), а для обмена по API используется Base64. Всегда проверяйте тип и размер результата перед использованием.