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

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

Как работать с двоичными данными в 1С

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

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

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

Типичные сценарии: загрузка картинки в справочник, выгрузка документа в PDF, обмен файлами с внешними системами через HTTP, распаковка архивов, полученных от контрагентов. В каждом случае есть свои ограничения по размеру, кодировке и месту хранения, которые важно учитывать заранее.

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

Тип ДвоичныеДанные — это неизменяемый объект, содержащий массив байтов. «Неизменяемый» означает, что после создания объект нельзя модифицировать: любая операция преобразования создаёт новый объект. Это важно при работе с большими файлами — каждое копирование удваивает потребление памяти.

Получить двоичные данные проще всего из файла:

ДД = Новый ДвоичныеДанные("C:\Docs\dogovor.pdf");

Размер = ДД.Размер(); // размер в байтах

У объекта всего два полезных свойства: метод Размер() и возможность записи через Записать(ИмяФайла). Всё остальное — чтение по частям, поиск, конкатенация — делается через потоки и объекты ЧтениеДанных/ЗаписьДанных.

Чтение и запись файлов на диске

Базовый цикл работы с файлом: прочитать файл в двоичные данные, выполнить операции, записать результат обратно. Запись выполняется методом Записать():

ДД = Новый ДвоичныеДанные("C:\Temp\input.xlsx");

// ... обработка ...

ДД.Записать("C:\Temp\output.xlsx");

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

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

Хранение двоичных данных в базе

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

СпрОбъект = Справочники.Файлы.СоздатьЭлемент();

СпрОбъект.Наименование = ИмяФайла;

СпрОбъект.ДанныеФайла = Новый ХранилищеЗначения(ДД, Новый СжатиеДанных(9));

СпрОбъект.Записать();

Обратное извлечение — метод Получить() у значения реквизита. Конструктор хранилища поддерживает сжатие данных, что заметно экономит место для текстовых и офисных файлов, но почти бесполезно для уже сжатых форматов (JPEG, ZIP, MP4).

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

Передача через Base64 и временное хранилище

Двоичные данные нельзя передать как текст напрямую — байты испортятся. Для обмена через XML, JSON, HTTP и веб-сервисы используется кодировка Base64, которая представляет байты в виде безопасной строки:

Строка64 = Base64Строка(ДД);

ДДОбратно = Base64Значение(Строка64);

Учитывайте, что Base64 увеличивает объём данных примерно на треть. Для обмена файлами по HTTP предпочтительнее передавать тело запроса как двоичные данные без кодирования — объекты HTTPЗапрос умеют работать с ДвоичныеДанные напрямую через УстановитьТелоИзДвоичныхДанных() и ПолучитьТелоКакДвоичныеДанные().

Временное хранилище — стандартный мост между клиентом и сервером. Адрес в хранилище действует ограниченное время (по умолчанию — время жизни формы или сеанса), поэтому извлекайте данные сразу и не передавайте адрес между сеансами.

bsl
ДД = ПолучитьИзВременногоХранилища(АдресХранилища);
Строка = Base64Строка(ДД);
ДД2 = Base64Значение(Строка);
ДД2.Записать(ИмяФайла);

Потоки и порционная обработка больших файлов

Объекты Поток, ФайловыйПоток и ПотокВПамяти позволяют читать и писать данные частями. Это единственный безопасный способ обработки файлов, размер которых сопоставим с объёмом доступной памяти:

Поток = ФайловыеПотоки.ОткрытьДляЧтения(ИмяФайла);

Буфер = Новый БуферДвоичныхДанных(1048576); // 1 МБ

Пока Поток.Прочитать(Буфер, 0, Буфер.Размер) > 0 Цикл

// обработка порции

КонецЦикла;

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

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

Способы обработки файлов

Новый ДвоичныеДанные(файл)

Подходит для небольших файлов: простой код, но весь файл в памяти

ФайловыйПоток + БуферДвоичныхДанных

Для больших файлов: порционная обработка, сложнее код

ПотокВПамяти

Когда файл формируется в памяти и далее уходит в хранилище или HTTP без записи на диск

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

Самая частая ошибка — попытка прочитать двоичные данные как текст через ЧтениеТекста или наоборот. Если файл текстовый (XML, CSV, log) — используйте текстовые объекты с явным указанием кодировки; если бинарный — только двоичные механизмы. Смешение приводит к порче данных из-за перекодировки.

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

После записи файла проверяйте результат: существование файла, его размер и, при необходимости, контрольную сумму. Для критичных обменов согласуйте с контрагентом проверку по хешу (MD5/SHA) — объект ХешированиеДанных позволяет вычислить хеш прямо из 1С.

Типичные ошибки
01
Чтение бинарного файла через ЧтениеТекста — данные портятся перекодировкой
02
Загрузка большого файла целиком в память — аварийное завершение rphost
03
Использование адреса временного хранилища после очистки — ошибка получения данных
04
Хранение больших файлов в базе без сжатия и без томов — раздувание базы и медленные бэкапы
05
Передача файла через Base64 там, где HTTP умеет двоичное тело — лишняя треть трафика
Контрольные точки

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

Размер записанного файла
Норма

Совпадает с размером исходных данных

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

Файл меньше или нулевой размер — запись оборвалась

Открытие файла внешней программой
Норма

PDF/картинка/архив открывается без ошибок

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

Программа сообщает о повреждении — данные испорчены при передаче

Хеш-сумма до и после передачи
Норма

Хеши совпадают

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

Хеши различаются — где-то произошла перекодировка

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

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

Нет, объект ДвоичныеДанные неизменяем. Для модификации откройте данные через ЧтениеДанных, измените нужные байты через БуферДвоичныхДанных и соберите результат ЗаписьДанных в новый поток.

Как передать файл с клиента на сервер без расширения работы с файлами?

Используйте метод НачатьПомещениеФайлаВоВременноеХранилище — в веб-клиенте он работает без расширения, хотя для больших файлов расширение всё же предпочтительнее по скорости и стабильности.

Чем отличается ПотокВПамяти от обычного файла?

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

Почему файл после передачи через веб-сервис не открывается?

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

Есть ли ограничение на размер двоичных данных в 1С?

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

Как сохранить картинку из базы на диск?

Получите значение реквизита типа ХранилищеЗначения методом Получить() — результатом будут двоичные данные, которые записываются методом Записать(ИмяФайла) с нужным расширением.