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

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

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

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

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

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

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

Что такое временное хранилище и когда нужно удалять данные

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

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

Удалять данные вручную следует сразу после того, как они перестали быть нужны: файл записан в базу, отчёт отправлен пользователю, картинка сохранена в реквизит объекта. Это особенно критично в циклах — например, при пакетной загрузке сотен файлов в одном сеансе.

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

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

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

&НаСервере

Процедура ОбработатьФайлНаСервере(АдресХранилища)

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

// ... обработка данных, запись в базу ...

// Освобождаем память сразу после использования

УдалитьИзВременногоХранилища(АдресХранилища);

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

Хорошая практика — оборачивать удаление в конструкцию Попытка...Исключение...КонецПопытки не ради защиты от ошибки самого удаления, а чтобы гарантировать вызов даже при сбое обработки. Для этого удаление помещают после блока обработки или в отдельную процедуру-обёртку.

bsl
Если ЭтоАдресВременногоХранилища(АдресХранилища) Тогда
    УдалитьИзВременногоХранилища(АдресХранилища);
КонецЕсли;

Удаление после интерактивной загрузки файла

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

Загрузка через НачатьПомещениеФайла

При использовании асинхронного метода НачатьПомещениеФайла адрес хранилища приходит в описание оповещения. Удаление выполняется в конце серверной обработки, которой этот адрес передаётся:

&НаКлиенте

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

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

ЗагрузитьДанныеНаСервере(Адрес); // внутри — обработка и удаление

КонецЕсли;

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

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

Множественная загрузка

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

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

Особые случаи и ограничения

Метод УдалитьИзВременногоХранилища недоступен в некоторых контекстах исполнения. В частности, его нельзя вызывать на тонком клиенте и веб-клиенте в клиентском коде — метод работает на сервере и в толстом клиенте. Поэтому удаление всегда выносят в серверную процедуру, даже если адрес получен на клиенте.

Второй нюанс — хранилище, привязанное к уникальному идентификатору формы. Если данные помещены с указанием УникальныйИдентификатор формы, они автоматически удалятся при её закрытии. Явное удаление в этом случае не обязательно, но допустимо и полезно, если данные стали не нужны раньше закрытия формы.

Третий момент — фоновые задания. Если адрес передан в фоновое задание через ФоновыеЗадания.Выполнить, удалять данные до завершения задания нельзя: фоновый процесс получит их по адресу. Удаление выполняется либо в конце самого фонового задания (если адрес ему доступен), либо в основном сеансе после получения сообщения о завершении.

Проверка адреса и диагностика проблем

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

Признак того, что данные уже удалены или срок их жизни истёк: ПолучитьИзВременногоХранилища возвращает Неопределено или вызывает исключение в зависимости от версии платформы и контекста. Если ваша обработка неожиданно получает пустые данные — первым делом проверьте, не был ли адрес удалён раньше времени в другом месте кода.

Для поиска «утечек» — адресов, которые забыли удалить, — полезно логировать пары «помещение/удаление» в журнал регистрации при отладке массовых операций. Расхождение счётчиков покажет, в какой ветке кода данные остаются в памяти.

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

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

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

Метод выполняется без исключения, повторный вызов с тем же адресом не вызывает ошибки

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

Ошибка «Метод не доступен» — вызов идёт в клиентском контексте, вынесите удаление на сервер

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

После удаления данные не нужны; если получение всё же требуется — оно должно происходить до удаления

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

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

Потребление памяти при массовой загрузке
Норма

Память сеанса не растёт пропорционально количеству обработанных файлов

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

Память растёт с каждым файлом — удаление не выполняется в цикле

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

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

Вторая ошибка — преждевременное удаление. Код удаляет адрес сразу после ПолучитьИзВременногоХранилища, но затем пытается передать тот же адрес в другую процедуру или на клиент для скачивания. Результат — пустые данные и неочевидные сбои.

Третья группа проблем связана с контекстом: попытка вызвать УдалитьИзВременногоХранилища в клиентской процедуре тонкого клиента приводит к ошибке компиляции или выполнения. Правило простое: все операции с хранилищем, кроме интерактивного помещения файла, выполняются на сервере.

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

Альтернативы и смежные приёмы

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

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

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

Итог

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

Удаление файла из временного хранилища выполняется серверным методом УдалитьИзВременногоХранилища(Адрес). Сохраняйте адрес при помещении, удаляйте данные сразу после обработки во всех ветках кода, не удаляйте адрес до завершения фоновых заданий, которые его используют, и проверяйте адрес функцией ЭтоАдресВременногоХранилища перед обращением.

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

Что произойдёт, если вызвать УдалитьИзВременногоХранилища с несуществующим адресом?

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

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

В тонком и веб-клиенте метод УдалитьИзВременногоХранилища недоступен. Удаление выполняется в серверной процедуре: клиент передаёт адрес, сервер освобождает данные. В толстом клиенте метод доступен и в клиентском контексте.

Файл удалится сам, если не вызывать удаление?

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

Как удалить данные, если адрес потерян?

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

Нужно ли удалять данные, помещённые с идентификатором формы?

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

Чем отличается удаление из временного хранилища от удаления временного файла на диске?

Это разные механизмы. Временное хранилище — память сервера, управляемая платформой, очистка через УдалитьИзВременногоХранилища. Временные файлы на диске создаются методами вроде ПолучитьИмяВременногоФайла и удаляются методом УдалитьФайлы — платформа за ними не следит.