Разработка и Конфигурация · 10 мин
Как получить двоичные данные файла в 1С
Как получить двоичные данные файла в 1С: конструктор ДвоичныеДанные, чтение с диска, из хранилища значений, временного хранилища. Примеры кода и ошибки.
Двоичные данные в 1С — это универсальный способ представить содержимое любого файла (картинки, PDF, архива, Excel-документа) в виде объекта, с которым можно работать программно: сохранить в базу, передать через веб-сервис, отправить по HTTP или записать в другое место. Тип ДвоичныеДанные доступен и на толстом, и на тонком, и на веб-клиенте, что делает его стандартным инструментом обмена файлами между клиентом и сервером.
Способов получить двоичные данные несколько: напрямую из файла на диске, из хранилища значения реквизита объекта, из временного хранилища после интерактивного выбора файла пользователем, из потока в памяти. Выбор зависит от того, где файл находится и на какой стороне (клиент или сервер) выполняется код.
Ниже разобраны рабочие примеры кода, ограничения платформы, типичные ошибки вроде перепутанных контекстов выполнения и способы проверить, что данные получены корректно.
Что такое тип ДвоичныеДанные и когда он нужен
Объект типа ДвоичныеДанные хранит содержимое файла в виде последовательности байт. Платформа не анализирует внутренний формат — для неё это просто массив байт заданного размера. У объекта есть методы Записать() для сохранения в файл и Размер() для получения длины в байтах.
Типичные сценарии использования: сохранение вложений в реквизит типа ХранилищеЗначения, передача файлов в HTTP-сервисы и веб-сервисы, формирование пакетов обмена, работа с криптографией и подписанием, чтение картинок для вывода в формы и печатные формы.
Получение двоичных данных из файла на диске
Базовый способ — конструктор с указанием полного пути к файлу. Код выполняется там, где физически доступен файл: если путь указывает на диск сервера, код должен выполняться на сервере.
ДвоичныеДанныеФайла = Новый ДвоичныеДанные("C:\Обмен\order.xml");
РазмерФайла = ДвоичныеДанныеФайла.Размер(); // размер в байтах
Если файла не существует или нет прав на чтение, платформа вызовет исключение. Поэтому перед чтением полезно проверить существование файла:
ФайлНаДиске = Новый Файл("C:\Обмен\order.xml");
Если ФайлНаДиске.Существует() Тогда
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ФайлНаДиске.ПолноеИмя);
Иначе
ВызватьИсключение "Файл не найден: " + ФайлНаДиске.ПолноеИмя;
КонецЕсли;
Получение файла от пользователя на клиенте
В управляемом приложении прямой доступ клиента к диску ограничен, а сервер не видит диск пользователя. Стандартная схема — асинхронное помещение файла во временное хранилище с последующей обработкой на сервере.
Интерактивный выбор через диалог
&НаКлиенте
Процедура ВыбратьФайл(Команда)
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект);
НачатьПомещениеФайла(ОписаниеОповещения, , , Истина, УникальныйИдентификаторФормы);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, Адрес, ВыбранноеИмяФайла, ДопПараметры) Экспорт
Если Результат Тогда
АдресХранилища = Адрес; // реквизит формы
ЗагрузитьНаСервере(АдресХранилища);
КонецЕсли;
КонецПроцедуры
После помещения файл доступен на сервере по адресу временного хранилища. Извлечение выполняется методом ПолучитьИзВременногоХранилища, который возвращает именно объект ДвоичныеДанные.
&НаСервере
Процедура ЗагрузитьНаСервере(Адрес)
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(Адрес);
// дальше: сохранить в реквизит, распаковать, записать на диск сервера
КонецПроцедуры
- 1Вызовите НачатьПомещениеФайла с описанием оповещения и УникальныйИдентификатор формы
- 2В обработчике оповещения проверьте Результат и сохраните адрес временного хранилища
- 3Передайте адрес в серверную процедуру
- 4На сервере вызовите ПолучитьИзВременногоХранилища(Адрес) — получите ДвоичныеДанные
- 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
Отдельная группа проблем — большие файлы. Загрузка файла целиком в память при обмене по HTTP может приводить к существенному расходу оперативной памяти и тайм-аутам. Для объёмных данных рассмотрите передачу частями через потоки или файловый обмен через общий каталог, а не прямое помещение в тело запроса.
Часто задаваемые вопросы
Как получить двоичные данные картинки из реквизита справочника?
Прочитайте реквизит типа ХранилищеЗначения через запрос или объектную модель и вызовите у него метод Получить(). Результат и будет объектом ДвоичныеДанные, который можно записать в файл или поместить во временное хранилище для показа в форме.
Можно ли получить двоичные данные файла без сохранения на диск?
Да. Если данные уже в памяти (например, получены по HTTP или сформированы программно), используйте потоки: запишите данные в ПотокВПамяти и вызовите ПолучитьДвоичныеДанные(). Промежуточный файл на диске не требуется.
Почему ПолучитьИзВременногоХранилища возвращает Неопределено?
Чаще всего адрес указывает на уже очищенное хранилище: форма закрыта, данные удалены явно или адрес получен без привязки к УникальныйИдентификатор формы и потерян. Проверьте, что адрес актуален и передаётся в ту же сессию.
Чем ДвоичныеДанные отличаются от ХранилищаЗначения?
ДвоичныеДанные — само содержимое файла в байтах. ХранилищеЗначения — обёртка для сохранения произвольного значения (в том числе двоичных данных) в реквизите базы со сжатием. Чтобы получить данные из хранилища, вызывают метод Получить().
Как передать двоичные данные с клиента на сервер без временного хранилища?
Для небольших данных можно закодировать их в Base64 функцией Base64Строка() на клиенте и передать строку параметром в серверную процедуру, где декодировать через Base64Значение(). Для файлов заметного размера этот способ неэффективен — лучше временное хранилище.
Работает ли Новый ДвоичныеДанные в веб-клиенте?
Конструктор доступен, но прямое чтение произвольного файла с диска в веб-клиенте ограничено браузерной безопасностью. Практический путь — НачатьПомещениеФайла с диалогом выбора, который работает в веб-клиенте штатно.
Что важно запомнить
Файл с диска читается конструктором Новый ДвоичныеДанные(Путь) на той стороне, где файл физически доступен. Файл пользователя передаётся на сервер через временное хранилище, из реквизита базы данные извлекаются методом Получить(), а для обмена по API используется Base64. Всегда проверяйте тип и размер результата перед использованием.