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

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

Как получить файл из временного хранилища в 1С

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

Временное хранилище в 1С — это механизм платформы, который позволяет передавать данные (в первую очередь двоичные данные файлов и значения) между клиентом и сервером, а также между вызовами сервера. Когда пользователь выбирает файл через диалог или файл помещается программно, платформа возвращает не сами данные, а навигационную ссылку — адрес вида e1cib/tempstorage/.... По этому адресу данные можно получить позже в рамках сеанса.

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

Ниже разобраны основные сценарии: помещение файла в хранилище, получение данных на сервере и на клиенте, сохранение файла на диск, работа с временем жизни хранилища и типичные ошибки, из-за которых вместо файла приходит Неопределено.

Что такое временное хранилище и зачем оно нужно

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

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

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

Как поместить файл во временное хранилище

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

&НаКлиенте

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

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

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

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

&НаКлиенте

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

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

АдресХранилища = Адрес;

ИмяФайла = ВыбранноеИмяФайла;

КонецЕсли;

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

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

Получение файла из временного хранилища на сервере

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

&НаСервере

Процедура СохранитьФайлНаСервере()

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

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

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

КонецЕсли;

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

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

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

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

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

&НаКлиенте

Процедура СохранитьНаДиск(Команда)

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

Если ДвоичныеДанные <> Неопределено Тогда

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

КонецЕсли;

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

Для файловых операций на клиенте в современных версиях платформы потребуется расширение работы с файлами — в веб-клиенте без него запись на диск недоступна. Альтернатива — метод ПолучитьФайл, который сам запрашивает у пользователя каталог сохранения и корректно работает через браузер.

Время жизни хранилища и очистка данных

Хранилище автоматически очищается, но полагаться только на автоматику не стоит: при массовой загрузке файлов серверная память расходуется заметно. После того как данные получены и обработаны, вызовите УдалитьИзВременногоХранилища(Адрес) — это освободит ресурсы сразу.

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

Типичные ошибки при работе с хранилищем

Большинство проблем связано не с самой функцией получения, а с контекстом её вызова. Ниже — ситуации, которые встречаются чаще всего.

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

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

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

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

Возвращаемое значение
Норма

Объект типа ДвоичныеДанные с ненулевым размером

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

Неопределено или пустые данные

Запись на диск
Норма

Файл создан, открывается и размер совпадает с исходным

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

Файл нулевого размера или не открывается

Повторное получение
Норма

До вызова УдалитьИзВременногоХранилища данные доступны повторно

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

Второй вызов возвращает Неопределено до явного удаления

Альтернативы временному хранилищу

Не каждая задача требует временного хранилища. Если данные нужны долго, правильнее сразу сохранять их в базу: реквизит типа ХранилищеЗначения, механизм присоединённых файлов БСП или файловые тома. Это снимает проблему времени жизни и позволяет обращаться к файлу из любого сеанса.

Для передачи небольших текстовых данных (XML, JSON) между клиентом и сервером хранилище вообще не нужно — строки передаются через параметры серверных процедур напрямую. Хранилище оправдано именно для двоичных данных и крупных структур, которые неудобно гонять через параметры.

Итог

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

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

Частые вопросы

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

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

Можно ли получить файл из хранилища в фоновом задании?

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

Чем ПолучитьИзВременногоХранилища отличается от ПолучитьФайл?

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

Как узнать размер данных, не извлекая их из хранилища?

Штатного способа получить размер без извлечения нет. Практическое решение — сохранять размер отдельно в момент помещения файла (на клиенте размер известен до загрузки) и передавать его вместе с адресом.

Можно ли использовать временное хранилище для постоянного хранения файлов?

Нет. Хранилище очищается при закрытии формы, завершении сеанса или по таймауту. Для постоянного хранения используйте реквизит типа ХранилищеЗначения, справочник присоединённых файлов или файловые тома.