При автоматизации выгрузок, обменов или резервного копирования часто требуется сформировать архив и очистить каталог от исходных неупакованных файлов. Разработчики нередко ищут параметр или метод в объекте ЗаписьZipФайла, который позволял бы автоматически удалять упакованные файлы по аналогии с внешними архиваторами. Рассмотрим, как устроена работа с zip-архивами в платформе 1С:Предприятие, почему автоматическое удаление не встроено в объект архивации и как правильно организовать очистку файлов в коде.
В интерактивных архиваторах (например, WinRAR или 7-Zip) существует опция «Удалять файлы после архивации». Однако в программном интерфейсе 1С объект ЗаписьZipФайла отвечает исключительно за упаковку данных в архивный файл. Разделение операций архивации и удаления сделано намеренно по следующим причинам:
ЗаписьZipФайла удерживает дескрипторы открытых исходных файлов в операционной системе вплоть до вызова метода Записать(). Попытка удалить файл до завершения записи архива приведет к ошибке доступа на уровне операционной системы.Проанализируем базовый и наиболее надежный способ очистки исходных файлов средствами платформы 1С. Для безопасного выполнения операций упаковываемый файл или список файлов удаляется только после успешного завершения метода Записать() и обязательной проверки в блоке обработки исключений.
Разберем по шагам типовой алгоритм:
ЗаписьZipФайла и инициализируем архив.Добавить().Записать().УдалитьФайлы().Посмотрим на пример безопасной реализации на сервере:
ИмяФайлаАрхива = "C:\Exchange\Export.zip";
ИмяИсходногоФайла = "C:\Exchange\Data.xml";
Архиватор = Новый ЗаписьZipФайла(ИмяФайлаАрхива);
Попытка
Архиватор.Добавить(ИмяИсходногоФайла);
Архиватор.Записать();
// Удаляем исходный файл только после успешного закрытия архива
УдалитьФайлы(ИмяИсходногоФайла);
Исключение
// В случае ошибки архив не сформирован корректно, исходный файл сохранен
ЗаписьЖурналаРегистрации("Архивация", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
ВызватьИсключение;
КонецПопытки;
Если операция выполняется в клиентском коде управляемого приложения при установленном режиме «Запрещать открытие модальных окон» или запрете синхронных вызовов, прямой вызов УдалитьФайлы() вызовет исключение платформы. В таких сценариях применяются асинхронные методы работы с файловой системой.
Рассмотрим пример с использованием асинхронного вызова через конструкцию Ждать:
&НаКлиенте
Асинх Процедура УпаковатьИОчиститьФайл(ИмяФайлаАрхива, ИмяИсходногоФайла)
Архиватор = Новый ЗаписьZipФайла(ИмяФайлаАрхива);
Попытка
Архиватор.Добавить(ИмяИсходногоФайла);
Архиватор.Записать();
// Асинхронное удаление на клиенте
Ждать УдалитьФайлыАсинх(ИмяИсходногоФайла);
Исключение
ПоказатьПредупреждение(, "Не удалось заархивировать файл: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Для версий платформы без поддержки ключевого слова Ждать применяется метод НачатьУдалениеФайлов() с передачей описания оповещения.
Когда выгружаемые данные формируются программно исключительно для упаковки в архив, удобно сохранять их в отдельном временном каталоге. Для этого используется метод ПолучитьИмяВременногоФайла().
Разберем по шагам этот подход:
УдалитьФайлы(ВременныйКаталог), избавляясь от необходимости перебирать каждый файл по отдельности.Если в инфраструктуре применяются внешние консольные архиваторы (например, 7-Zip или WinRAR), флаг удаления файлов можно передать непосредственно в параметрах командной строки:
-sdel предписывает утилите удалить исходные файлы после успешного добавления в архив (например, 7z.exe a archive.zip C:\Data\*.xml -sdel).-df удаляет файлы после помещения в архив.ЗапуститьПриложение().Однако при наличии встроенного объекта ЗаписьZipФайла и штатной процедуры УдалитьФайлы() использование внешних утилит избыточно, если не требуются специфические форматы сжатия или алгоритмы шифрования.