Разработка и Конфигурация · 12 мин
1С: как создать файл из двоичных данных
Как в 1С создать файл из двоичных данных: методы Записать и ПолучитьДвоичныеДанные, работа с хранилищем значений, примеры кода, ошибки и проверка результата.
Двоичные данные в 1С встречаются повсюду: картинки в справочниках, PDF-документы в присоединенных файлах, архивы, полученные из веб-сервисов, ответы внешних API. Чтобы использовать такие данные за пределами системы — открыть картинку, отправить файл по почте, отдать его пользователю на скачивание, — их нужно сохранить на диск в виде обычного файла. Делается это одним методом Записать(), но вокруг него есть нюансы: откуда брать данные, как обращаться с хранилищем значений, как работать на сервере и в тонком клиенте.
В материале разобраны основные сценарии: запись двоичных данных из реквизита объекта, из временного хранилища, из строки Base64 и из HTTP-ответа. Приведены готовые фрагменты кода на встроенном языке 1С, способы проверить, что файл записался корректно, и разбор типичных ошибок, из-за которых файл получается пустым или «битым».
Что такое двоичные данные в 1С и где они хранятся
Двоичные данные (тип ДвоичныеДанные) — это набор байтов без интерпретации: внутри может быть что угодно, от картинки JPEG до архива ZIP. Сама платформа не знает, что за файл внутри, — тип содержимого определяется расширением имени файла, которое вы задаёте при записи, или анализом сигнатуры (первых байтов).
Чаще всего двоичные данные хранятся в реквизитах типа ХранилищеЗначения. Это специальный тип, который сериализует и сжимает содержимое. Чтобы получить из него двоичные данные, вызывают метод Получить(). Важно понимать: напрямую присвоить реквизит-хранилище переменной нельзя — вы получите объект хранилища, а не сами байты.
Ещё два частых источника — временное хранилище (куда помещаются файлы при интерактивной загрузке через НачатьПомещениеФайла) и внешние источники: HTTP-сервисы, почта, COM-объекты. Во всех случаях итоговая операция одна и та же — вызов Записать() с указанием полного пути к файлу.
Базовый способ: метод Записать()
У объекта типа ДвоичныеДанные есть два ключевых метода: Записать(ИмяФайла) — сохраняет данные в файл, и Размер() — возвращает размер в байтах. Обратная операция — конструктор Новый ДвоичныеДанные(ИмяФайла), который читает файл с диска.
Минимальный пример — сохранение картинки из реквизита справочника в файл на диске:
ДвоичныеДанные = НоменклатураОбъект.Картинка.Получить();
Если ДвоичныеДанные = Неопределено Тогда
ВызватьИсключение "В хранилище нет данных";
КонецЕсли;
ИмяФайла = "C:\Temp\picture.jpg";
ДвоичныеДанные.Записать(ИмяФайла);
Обратите внимание на проверку на Неопределено: если реквизит пустой, Получить() вернёт именно его, и попытка вызвать Записать() вызовет ошибку «Значение не является значением объектного типа». Это одна из самых частых ошибок у начинающих разработчиков.
Путь к файлу должен включать имя и расширение. Если каталога не существует, метод выбросит исключение — создавайте каталог заранее через СоздатьКаталог() или используйте КаталогВременныхФайлов(), который гарантированно существует.
- 1Получите двоичные данные из источника: Хранилище.Получить() или ПолучитьИзВременногоХранилища()
- 2Проверьте, что результат не равен Неопределено и Размер() больше нуля
- 3Сформируйте полный путь с именем файла и корректным расширением
- 4Вызовите ДвоичныеДанные.Записать(Путь)
- 5Откройте файл подходящей программой и убедитесь, что он читается
Создание файла из временного хранилища
Когда пользователь загружает файл через форму, данные попадают во временное хранилище, а в код передаётся только адрес строкой вида e1cib/tempstorage/.... Чтобы получить сами байты, используется функция ПолучитьИзВременногоХранилища(Адрес). Она доступна только на сервере — в клиентском контексте вызов приведёт к ошибке.
Типичный серверный метод формы выглядит так:
&НаСервере
Процедура СохранитьФайлНаСервере(АдресВХранилище, ИмяФайла)
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВХранилище);
Если ТипЗнч(ДвоичныеДанные) <> Тип("ДвоичныеДанные") Тогда
ВызватьИсключение "По адресу нет двоичных данных";
КонецЕсли;
ДвоичныеДанные.Записать(КаталогВременныхФайлов() + ИмяФайла);
КонецПроцедуры
Проверка типа здесь важна: по адресу во временном хранилище может лежать не только ДвоичныеДанные, но и, например, таблица значений или адрес другого хранилища. Явная проверка через ТипЗнч() избавляет от трудноуловимых ошибок.
Создание файла из строки Base64
При обмене через HTTP-API и веб-сервисы файлы часто передаются в виде строки Base64 — это текстовое представление бинарных данных. Платформа 1С имеет пару функций для конвертации: Base64Строка() и Base64Значение(). Для создания файла нужна вторая — она преобразует строку обратно в двоичные данные.
СтрокаBase64 = ОтветСервиса.file_content; // строка из JSON
ДвоичныеДанные = Base64Значение(СтрокаBase64);
ДвоичныеДанные.Записать(КаталогВременныхФайлов() + "document.pdf");
Две практические тонкости. Первая: некоторые API добавляют к строке префикс вида data:image/png;base64, — его нужно отрезать до вызова Base64Значение(), иначе получите ошибку или повреждённые данные. Вторая: в строке могут встречаться переводы строк (некоторые сервисы разбивают Base64 на строки по 76 символов) — перед конвертацией удалите их через СтрЗаменить().
Клиент или сервер: где записывать файл
Метод Записать() выполняется там, где выполняется код. Если вызвать его в серверной процедуре, файл появится на диске сервера 1С, и пользователь его не увидит. Если в клиентской — на компьютере пользователя, но в тонком и веб-клиенте действуют ограничения: доступ к файловой системе требует расширения работы с файлами и разрешения пользователя.
Стандартный безопасный сценарий «сформировать и отдать пользователю» выглядит так: на сервере данные записываются во временный файл или помещаются напрямую во временное хранилище через ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификаторФормы), затем на клиенте вызывается НачатьПолучениеФайлаССервера() или ПолучитьФайл() — и пользователь сохраняет файл в выбранную папку.
&НаСервере
Функция ПодготовитьФайл()
ДвоичныеДанные = Объект.ДанныеФайла.Получить();
Возврат ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
КонецФункции
&НаКлиенте
Процедура Скачать(Команда)
Адрес = ПодготовитьФайл();
ПолучитьФайл(Адрес, Объект.ИмяФайла, Истина);
КонецПроцедуры
Как выбрать действие
Проверка результата и типичные ошибки
После записи файла стоит убедиться, что результат корректен. Минимальная проверка — существование файла и его размер: создайте объект Файл, вызовите Существует() и сравните Размер() с Размер() исходных двоичных данных. Совпадение размеров — хороший признак, хотя не гарантия целостности содержимого.
Более надёжный способ — открыть файл профильной программой: картинку — просмотрщиком, PDF — читалкой, архив — архиватором. Если файл «не открывается», чаще всего виноваты: неверное расширение, обрезанная строка Base64 или попытка записать текстовые данные как двоичные (и наоборот).
Отдельная группа проблем — права доступа. На сервере код выполняется под учётной записью службы агента сервера 1С, и у неё может не быть прав на произвольные каталоги (например, на сетевые шары или C:\Users\...). Используйте КаталогВременныхФайлов() или специально выделенный каталог с выданными правами.
Как проверить результат
Файл существует, размер совпадает с Размер() двоичных данных
Файл отсутствует или размер 0 байт — данные не записались
Картинка отображается, PDF открывается, архив распаковывается
Программа сообщает о повреждении файла — данные искажены (часто из-за Base64 или текстовой обработки)
Файл появился в ожидаемом каталоге на нужной машине
Файл создан на сервере, а ищется на клиенте (или наоборот)
Ограничения и безопасная работа
Размер обрабатываемых данных ограничен доступной оперативной памятью: двоичные данные целиком загружаются в память. Файлы в сотни мегабайт могут заметно нагрузить сервер, особенно при параллельной работе пользователей. Для больших файлов в типовых конфигурациях используется механизм присоединенных файлов (БСП), который хранит данные в томах на диске и работает с ними порционно — не изобретайте собственный велосипед, если подсистема уже есть в конфигурации.
Временные файлы после обработки удаляйте явно методом УдалитьФайлы() — иначе каталог временных файлов на сервере будет разрастаться. Учтите, что при фоновом выполнении и в регламентных заданиях клиентского контекста нет вообще: все операции с файлами там выполняются только на сервере.
И последнее: никогда не обрабатывайте двоичные данные через ТекстовыйДокумент или ЧтениеТекста/ЗаписьТекста. Эти объекты выполняют перекодировку символов, и бинарное содержимое будет безвозвратно повреждено. Для байтов — только ДвоичныеДанные, Поток и ЧтениеДанных/ЗаписьДанных.
Что важно запомнить
Файл создаётся методом ДвоичныеДанные.Записать(Путь). Данные берут из хранилища значения, временного хранилища, Base64 или HTTP-ответа. Проверяйте данные на Неопределено и размер, учитывайте контекст исполнения (клиент/сервер) и удаляйте временные файлы после использования.
Частые вопросы
Как сохранить картинку из справочника номенклатуры в файл?
Получите значение реквизита-хранилища методом Получить(), проверьте его на Неопределено, затем вызовите Записать() с полным путём, например: Данные.Записать("C:\Temp\img.jpg"). Расширение должно соответствовать реальному формату картинки, иначе просмотрщик её не откроет.
Почему файл создаётся, но не открывается?
Три основные причины: неверное расширение имени файла, повреждённые данные (например, строка Base64 с префиксом data: или переносами строк) и обработка бинарных данных текстовыми объектами, которая искажает байты. Сравните размер файла с размером исходных двоичных данных — несовпадение указывает на повреждение.
Как передать созданный файл пользователю из серверной процедуры?
Поместите двоичные данные во временное хранилище функцией ПоместитьВоВременноеХранилище(), верните адрес на клиент и вызовите ПолучитьФайл(Адрес, ИмяФайла, Истина) — пользователь увидит диалог сохранения.
Можно ли создать файл в фоновом задании?
Да, но только на сервере: в фоновом задании нет клиентского контекста. Записывайте файл в каталог временных файлов сервера или сразу отправляйте его дальше (по почте, через HTTP), не рассчитывая на интерактивное взаимодействие с пользователем.
Чем ПолучитьДвоичныеДанныеИз строки Base64 отличается от Base64Значение?
Base64Значение() — стандартная функция платформы, преобразующая строку Base64 в ДвоичныеДанные. Отдельной функции ПолучитьДвоичныеДанные в платформе нет; иногда так называют самописные обёртки в конфигурациях. Используйте Base64Значение() после очистки строки от префиксов и переносов.
Как ограничить размер записываемого файла?
Платформа не накладывает жёсткого лимита, но данные целиком размещаются в памяти. Проверяйте Размер() перед обработкой и отклоняйте слишком большие файлы на уровне прикладной логики. Для больших объёмов рассмотрите потоковую работу через ЧтениеДанных и ЗаписьДанных или механизм присоединенных файлов БСП.