Разработка и Конфигурация · 10 мин
Чтение файла как двоичных данных в 1С
Как в 1С прочитать файл как двоичные данные: объект ДвоичныеДанные, чтение с диска, из хранилища значений, Base64, примеры кода и типичные ошибки.
Задача получить содержимое файла в виде двоичных данных встречается в 1С постоянно: отправка вложений по HTTP, обмен с внешними API, выгрузка изображений и документов, формирование архивов, передача файлов между базами. Встроенный язык предоставляет для этого специальный тип ДвоичныеДанные, который читается из файла одной строкой кода и дальше используется практически везде — от веб-сервисов до временного хранилища.
Главное, что нужно понять сразу: двоичные данные в 1С — это не строка и не массив байт в привычном смысле, а неизменяемый объект, который нельзя редактировать по частям. Получить его можно из файла на диске, из потока, из Base64-строки или из хранилища значений. Выбор способа зависит от того, где лежит источник и на какой стороне — клиенте или сервере — выполняется код.
Ниже разобраны все рабочие способы чтения, ограничения тонкого и веб-клиента, работа с большими файлами через потоки и типичные ошибки, из-за которых файл читается пустым или код падает с исключением.
Базовый способ: конструктор «Новый ДвоичныеДанные»
Самый простой и самый частый вариант — передать путь к файлу в конструктор объекта ДвоичныеДанные. Платформа прочитает файл целиком и вернёт объект, с которым можно работать дальше.
ДвоичныеДанные = Новый ДвоичныеДанные("C:\Обмен\invoice.pdf");
Сообщить("Размер файла: " + ДвоичныеДанные.Размер() + " байт");
Метод Размер() возвращает размер данных в байтах — это удобный способ проверить, что файл прочитался не пустым. Если файл не существует или недоступен по указанному пути, платформа выбросит исключение, поэтому в реальном коде чтение стоит оборачивать в Попытка...Исключение или предварительно проверять существование файла.
Важный нюанс: конструктор выполняется там, где выполняется код. Если код работает на сервере 1С, путь должен быть доступен именно с сервера — локальный диск клиентской машины сервер не увидит. Это самая частая причина ошибки «файл не обнаружен» в клиент-серверном режиме.
Чтение файла на клиенте и передача на сервер
В управляемом приложении файл обычно выбирает пользователь на своём компьютере, а обработка происходит на сервере. Прямого чтения с клиентского диска на сервере нет, поэтому используется механизм временного хранилища: клиент помещает файл, получает адрес, а сервер забирает данные по этому адресу.
Асинхронное помещение файла
В современных версиях платформы модальные и синхронные вызовы работы с файлами запрещены или нежелательны, поэтому используется асинхронный метод НачатьПомещениеФайла с описанием оповещения.
&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект);
НачатьПомещениеФайла(ОписаниеОповещения, , , Истина, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
Если Результат Тогда
ОбработатьФайлНаСервере(Адрес);
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ОбработатьФайлНаСервере(Адрес)
ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
// дальше работаем с ДвоичныеДанные
КонецПроцедуры
Параметр Истина в НачатьПомещениеФайла включает диалог выбора файла. Если путь уже известен (например, файл сформирован на клиенте программно), диалог можно не показывать и передать путь вторым параметром.
Проверка результата
Признак успешного чтения — объект типа ДвоичныеДанные с размером больше нуля. Если ПолучитьИзВременногоХранилища вернуло строку или Неопределено, значит файл не был помещён: пользователь отменил диалог, адрес хранилища устарел или помещение выполнялось в другом сеансе.
Как проверить результат
Тип ДвоичныеДанные
Строка с адресом или Неопределено — файл не помещён
Размер() больше нуля и совпадает с размером файла на диске
Ноль байт — прочитан пустой или несуществующий файл
Установлено расширение работы с файлами
Ошибка при вызове методов работы с файлами
Чтение через потоки
Начиная с версии платформы 8.3.11, для работы с файлами доступны потоки. Они нужны, когда файл большой, когда данные приходят из сети, или когда нужно читать только часть файла, а не загружать всё в память.
Поток = ФайловыеПотоки.ОткрытьДляЧтения("C:\Обмен\bigdata.zip");
ПотокВывода = ПотокиВПамяти.Создать();
Поток.КопироватьВ(ПотокВывода);
ДвоичныеДанные = ПотокВывода.ЗакрытьИПолучитьДвоичныеДанные();
Поток.Закрыть();
Для небольших файлов потоки избыточны — конструктор Новый ДвоичныеДанные проще и читаемее. Но при размере в сотни мегабайт потоковая обработка снижает пиковое потребление памяти и позволяет читать файл порциями через БуферДвоичныхДанных.
Отдельный сценарий — чтение части файла. Метод Поток.Перейти(Смещение, ПозицияВПотоке.Начало) позволяет сместиться на нужный байт и прочитать только требуемый фрагмент, что полезно при разборе заголовков файлов без загрузки всего содержимого.
Двоичные данные из хранилища значений и реквизитов
Файлы, хранящиеся в базе (вложения, картинки, печатные формы), обычно лежат в реквизитах типа ХранилищеЗначения. Чтобы получить двоичные данные, значение нужно извлечь методом Получить().
Запрос = Новый Запрос("ВЫБРАТЬ Файл ИЗ Справочник.ПрисоединенныеФайлы ГДЕ Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", ФайлСсылка);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ДвоичныеДанные = Выборка.Файл.Получить();
КонецЕсли;
Метод Получить() возвращает значение, которое было помещено в хранилище, — обычно это именно ДвоичныеДанные, но встречаются конфигурации, где хранится строка Base64 или структура. Перед использованием полезно проверить тип через ТипЗнч().
В типовых конфигурациях (БСП) для работы с присоединёнными файлами есть готовые процедуры модуля РаботаСФайлами, которые уже возвращают двоичные данные. Если база построена на БСП, писать собственные запросы к служебным справочникам обычно не нужно.
Преобразование в Base64 и обратно
Двоичные данные нельзя напрямую вставить в JSON, XML-атрибут или строку запроса — для текстового представления используется кодировка Base64. В платформе для этого есть две пары функций: Base64Строка() / Base64Значение() и XMLСтрока() / XMLЗначение().
// Кодирование
СтрокаBase64 = Base64Строка(ДвоичныеДанные);
// Декодирование обратно в двоичные данные
ДвоичныеДанные = Base64Значение(СтрокаBase64);
Помните, что Base64 увеличивает объём данных примерно на треть. Для файла в 30 МБ строка займёт около 40 МБ в памяти, что при массовой обработке может привести к переполнению памяти сервера. Для крупных вложений лучше передавать данные через тело HTTP-запроса напрямую, без промежуточного кодирования в строку.
Запись двоичных данных обратно в файл
Обратная операция выполняется методом Записать(ИмяФайла). Это стандартный способ сохранить на диск вложение из письма, файл из хранилища или данные, полученные по HTTP.
ДвоичныеДанные.Записать("C:\Обмен\полученный_файл.xlsx");
Перед записью убедитесь, что каталог существует — платформа не создаёт недостающие папки автоматически. Также учитывайте права: на сервере запись выполняется от имени учётной записи агента сервера 1С, и у неё должен быть доступ к целевому каталогу.
Выбор способа под конкретную задачу
Способ чтения определяется тремя факторами: где лежит файл, где выполняется код и каков размер данных. Для серверного файла небольшого размера достаточно конструктора. Для клиентского файла — помещение в хранилище. Для больших файлов и сетевых источников — потоки.
Как выбрать действие
Что важно запомнить
Основной инструмент — конструктор Новый ДвоичныеДанные(Путь). Клиентские файлы сначала помещаются во временное хранилище, большие файлы читаются потоками, а для текстовой передачи данные кодируются в Base64. Всегда проверяйте существование файла, тип полученного значения и размер данных.
Частые вопросы
Можно ли прочитать файл как двоичные данные в веб-клиенте?
Да, но только через асинхронные методы помещения файла во временное хранилище и при установленном расширении работы с файлами в браузере. Прямой вызов Новый ДвоичныеДанные с локальным путём в веб-клиенте недоступен.
Как узнать размер файла до чтения?
Используйте объект Файл: Ф = Новый Файл(Путь); Если Ф.Существует() Тогда Размер = Ф.Размер();. Это позволяет проверить существование файла и оценить объём до загрузки в память.
Чем ДвоичныеДанные отличаются от объекта ЧтениеДанных?
ДвоичныеДанные — неизменяемый объект с готовым содержимым файла. ЧтениеДанных — последовательный читатель, который позволяет разбирать файл по частям: читать байты, числа и строки с указанием позиции. Для разбора форматов файлов удобнее второй вариант.
Почему Base64Значение возвращает ошибку или пустые данные?
Чаще всего строка содержит переносы строк, пробелы или префикс вида data:image/png;base64,, который нужно отрезать. Также функция чувствительна к повреждённым символам — строка должна быть валидным Base64.
Можно ли изменить часть двоичных данных без перезаписи всего объекта?
Нет, объект неизменяем. Нужно получить данные в поток или БуферДвоичныхДанных, внести изменения и сформировать новый объект ДвоичныеДанные из результата.
Как передать двоичные данные между сеансами или в фоновое задание?
Напрямую в параметры фонового задания двоичные данные передавать нельзя. Стандартный приём — поместить их во временное хранилище и передать в задание адрес, а внутри задания получить данные по этому адресу.