При работе с файловыми архивами в 1С, в частности с форматом ZIP, часто возникает необходимость создать архив с определенной внутренней структурой каталогов. Это особенно актуально, когда реализуется выгрузка прикрепленных файлов из различных объектов конфигурации для обмена или хранения. Стандартные методы добавления файлов могут приводить к нежелательному сохранению полных путей от корневого диска или, наоборот, к потере всей структуры каталогов. Давайте вместе разберем, как добиться желаемого результата.
Суть проблемы заключается в том, что при использовании метода Добавить() объекта ЗаписьZipФайла с параметром РежимСохраненияПутейZIP.СохранятьОтносительныеПути для одиночного файла, подкаталог может не сохраняться. Если же мы указываем РежимСохраненияПутейZIP.СохранятьПолныеПути, то в архив попадает весь путь от корневого диска (например, C:\Temp\МойКаталог\Файл.txt), что не всегда удобно и эстетично. Наша цель — получить структуру вида ZIP Архив - Каталог_1 - Файлы.
Мы выяснили, что для корректного сохранения относительных путей и вложенных каталогов внутри ZIP-архива, необходимо сначала подготовить нужную структуру файлов и папок во временном каталоге файловой системы. Подобный принцип часто применяется, когда выполняется выгрузка внешних отчетов и обработок во внешние папки. Затем мы будем добавлять в архив не отдельные файлы, а корневой временный каталог целиком, используя маску и соответствующие параметры метода Добавить(). Этот подход позволяет объекту ЗаписьZipФайла правильно интерпретировать относительные пути.
Рассмотрим подробнее шаги, которые нам предстоит выполнить.
ПотокВПамяти для формирования архива непосредственно в оперативной памяти, что удобно и эффективно, а также ЗаписьZipФайла.Добавить(), указав маску для всего временного каталога и ключевые параметры для сохранения относительных путей и рекурсивной обработки подкаталогов.Давайте посмотрим на пример кода, который демонстрирует описанный подход. Такая логика может быть полезна, если вам потребовалась выгрузка картинок номенклатуры в каталог с последующей их упаковкой для отправки.
// 1. Инициализация объектов для работы с ZIP-архивом
ПотокZIP = Новый ПотокВПамяти();
Архиватор = Новый ЗаписьZipФайла(ПотокZIP);
// 2. Подготовка временного каталога
ВрКаталог = КаталогВременныхФайлов();
ВрКаталог = ВрКаталог + "ТемпКаталог\"; // Создаем уникальный временный каталог для нашей операции
// Предположим, у нас есть таблица значений или коллекция РезультатФормирования.ТаблицаЭД
// с данными о файлах, которые нужно заархивировать.
Для Каждого СтрокаЭД Из РезультатФормирования.ТаблицаЭД Цикл
Контрагент = СтрокаЭД.Контрагент;
// Формируем полный путь для подкаталога внутри нашего временного каталога
ПолныйПуть = ВрКаталог + Контрагент.Наименование + "\";
// Проверяем существование подкаталога и создаем его, если он отсутствует
КаталогСуществует = Новый Файл(ПолныйПуть);
Если НЕ КаталогСуществует.Существует() Тогда
СоздатьКаталог(ПолныйПуть);
КонецЕсли;
// Формируем полный путь к временному файлу внутри созданного подкаталога
ВрФайл = ПолныйПуть + СтрокаЭД.ПолноеИмяФайла;
// Записываем двоичные данные файла во временный файл
СтрокаЭД.ДвоичныеДанныеФайла.Записать(ВрФайл);
КонецЦикла;
// 3. Добавление временного каталога в ZIP-архив
Маска = ВрКаталог + "*.*"; // Указываем маску для всех файлов во временном каталоге
Архиватор.Добавить(Маска, РежимСохраненияПутейZIP.СохранятьОтносительныеПути, РежимОбработкиПодкаталоговZIP.ОбрабатыватьРекурсивно);
// 4. Завершение процесса архивации и очистка
Архиватор.Записать(); // Завершаем формирование ZIP-архива
УдалитьФайлы(ВрКаталог); // Удаляем временный каталог со всеми файлами
ДвоичныеДанныеZIP = ПотокZIP.ЗакрытьИПолучитьДвоичныеДанные(); // Получаем двоичные данные архива из потока
// Сохраняем полученные двоичные данные в конечный ZIP-файл на диске
ДвоичныеДанныеZIP.Записать(Каталог + Строка.Организация.ФамилияИП + ".zip");
Добавить()Давайте проанализируем, почему именно такая комбинация параметров метода Добавить() позволяет нам добиться желаемой структуры:
Полное имя файла или маска (Маска = ВрКаталог + "*.*")
Вместо того чтобы добавлять каждый файл по отдельности, мы указываем путь к нашему корневому временному каталогу (ВрКаталог) и маску *.*. Это говорит архиватору, что нужно взять все файлы, находящиеся в этом каталоге и его подкаталогах. Важно: именно путь к ВрКаталог становится точкой отсчета для относительных путей.
РежимСохраненияПутейZIP.СохранятьОтносительныеПути
Этот режим является ключевым. Он указывает объекту ЗаписьZipФайла сохранять пути к файлам относительно каталога, указанного в первом параметре (в нашем случае, ВрКаталог). Таким образом, если внутри ВрКаталог у нас есть структура ТемпКаталог\Контрагент1\Файл1.txt, то в ZIP-архиве будет сохранено только Контрагент1\Файл1.txt. Именно это позволяет нам получить желаемую вложенность Каталог_1 - Файлы.
РежимСохраненияПутейZIP.СохранятьПолныеПути: сохраняет полный путь от корневого диска, что нам не подходит.РежимСохраненияПутейZIP.НеСохранятьПути: помещает в архив только имена файлов без какой-либо структуры каталогов.РежимОбработкиПодкаталоговZIP.ОбрабатыватьРекурсивно
Этот параметр критически важен, когда в первом параметре используется маска и нам нужно включить в архив не только файлы из указанного каталога, но и из всех его подкаталогов.
ПотокВПамяти: Как мы видели в примере, это позволяет формировать ZIP-архив без создания промежуточного файла на диске. В более специфических задачах иногда применяют даже хранилище значений в ZIP на чистом SQL, но для большинства бизнес-задач стандартных средств 1С в памяти достаточно.УдалитьФайлы(ВрКаталог)).Следуя этим рекомендациям и используя предложенный подход, вы сможете эффективно создавать ZIP-архивы с требуемой вложенной структурой каталогов в вашей конфигурации 1С.