Как создать ZIP-архив с вложенной структурой каталогов (например, `Каталог_1/Файлы`) в 1С?

Программист 1С v8.3 (Управляемые формы)
← К списку

При работе с файловыми архивами в 1С, в частности с форматом ZIP, часто возникает необходимость создать архив с определенной внутренней структурой каталогов. Например, нам требуется получить ZIP-файл, внутри которого будет папка Каталог_1, а уже в ней — нужные файлы. Стандартные методы добавления файлов могут приводить к нежелательному сохранению полных путей от корневого диска или, наоборот, к потере всей структуры каталогов. Давайте вместе разберем, как добиться желаемого результата.

Суть проблемы заключается в том, что при использовании метода Добавить() объекта ЗаписьZipФайла с параметром РежимСохраненияПутейZIP.СохранятьОтносительныеПути для одиночного файла, подкаталог может не сохраняться. Если же мы указываем РежимСохраненияПутейZIP.СохранятьПолныеПути, то в архив попадает весь путь от корневого диска (например, C:\Temp\МойКаталог\Файл.txt), что не всегда удобно и эстетично. Наша цель — получить структуру вида ZIP Архив - Каталог_1 - Файлы.

Ключевой подход: Сначала готовим структуру, затем архивируем каталогом

Мы выяснили, что для корректного сохранения относительных путей и вложенных каталогов внутри ZIP-архива, необходимо сначала подготовить нужную структуру файлов и папок во временном каталоге файловой системы. Затем мы будем добавлять в архив не отдельные файлы, а корневой временный каталог целиком, используя маску и соответствующие параметры метода Добавить(). Этот подход позволяет объекту ЗаписьZipФайла правильно интерпретировать относительные пути.

Рассмотрим подробнее шаги, которые нам предстоит выполнить.

  1. Инициализация объектов для работы с ZIP-архивом. Мы будем использовать ПотокВПамяти для формирования архива непосредственно в оперативной памяти, что удобно и эффективно, а также ЗаписьZipФайла.
  2. Подготовка временного каталога и структуры файлов. Создадим временный каталог на диске и внутри него — необходимую иерархию подкаталогов, куда сохраним все файлы, предназначенные для архива.
  3. Добавление временного каталога в ZIP-архив. Используем метод Добавить(), указав маску для всего временного каталога и ключевые параметры для сохранения относительных путей и рекурсивной обработки подкаталогов.
  4. Завершение процесса архивации и очистка. Запишем сформированный архив, получим его двоичные данные и удалим временные файлы.

Пример реализации

Давайте посмотрим на пример кода, который демонстрирует описанный подход, и разберем его по шагам.


// 1. Инициализация объектов для работы с ZIP-архивом
ПотокZIP       = Новый ПотокВПамяти();
Архиватор      = Новый ЗаписьZipФайла(ПотокZIP);

// 2. Подготовка временного каталога
ВрКаталог = КаталогВременныхФайлов();
ВрКаталог = ВрКаталог + "ТемпКаталог\"; // Создаем уникальный временный каталог для нашей операции

// Предположим, у нас есть таблица значений или коллекция РезультатФормирования.ТаблицаЭД
// с данными о файлах, которые нужно заархивировать.
Для Каждого СтрокаЭД Из РезультатФормирования.ТаблицаЭД Цикл
    Контрагент     = СтрокаЭД.Контрагент;
    // Формируем полный путь для подкаталога внутри нашего временного каталога
    ПолныйПуть     = ВрКаталог + Контрагент.Наименование + "\";

    // Проверяем существование подкаталога и создаем его, если он отсутствует
    КаталогСуществует = Новый Файл(ПолныйПуть);
    Если НЕ КаталогСуществует.Существует() Тогда
        СоздатьКаталог(ПолныйПуть);
    КонецЕсли;

    // Формируем полный путь к временному файлу внутри созданного подкаталога
    ВрФайл = ПолныйПуть + СтрокаЭД.ПолноеИмяФайла;
    // Записываем двоичные данные файла во временный файл
    СтрокаЭД.ДвоичныеДанныеФайла.Записать(ВрФайл);
КонецЦикла;

// 3. Добавление временного каталога в ZIP-архив
Маска = ВрКаталог + "*.*"; // Указываем маску для всех файлов во временном каталоге
Архиватор.Добавить(Маска, РежимСохраненияПутейZIP.СохранятьОтносительныеПути, РежимОбработкиПодкаталоговZIP.ОбрабатыватьРекурсивно);

// 4. Завершение процесса архивации и очистка
Архиватор.Записать(); // Завершаем формирование ZIP-архива

УдалитьФайлы(ВрКаталог); // Удаляем временный каталог со всеми файлами

ДвоичныеДанныеZIP = ПотокZIP.ЗакрытьИПолучитьДвоичныеДанные(); // Получаем двоичные данные архива из потока
// Сохраняем полученные двоичные данные в конечный ZIP-файл на диске
ДвоичныеДанныеZIP.Записать(Каталог + Строка.Организация.ФамилияИП + ".zip");

Подробный разбор параметров метода Добавить()

Давайте проанализируем, почему именно такая комбинация параметров метода Добавить() позволяет нам добиться желаемой структуры:

  1. Первый параметр: Полное имя файла или маска (Маска = ВрКаталог + "*.*")

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

  2. Второй параметр: РежимСохраненияПутейZIP.СохранятьОтносительныеПути

    Этот режим является ключевым. Он указывает объекту ЗаписьZipФайла сохранять пути к файлам относительно каталога, указанного в первом параметре (в нашем случае, ВрКаталог). Таким образом, если внутри ВрКаталог у нас есть структура ТемпКаталог\Контрагент1\Файл1.txt, то в ZIP-архиве будет сохранено только Контрагент1\Файл1.txt. Именно это позволяет нам получить желаемую вложенность Каталог_1 - Файлы.

    • РежимСохраненияПутейZIP.СохранятьПолныеПути: сохраняет полный путь от корневого диска (например, C:\Temp\ТемпКаталог\Контрагент1\Файл1.txt), что нам не подходит.
    • РежимСохраненияПутейZIP.НеСохранятьПути: помещает в архив только имена файлов без какой-либо структуры каталогов, что тоже не соответствует нашей задаче.
  3. Третий параметр: РежимОбработкиПодкаталоговZIP.ОбрабатыватьРекурсивно

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

    • РежимОбработкиПодкаталоговZIP.НеОбрабатывать: обрабатываются только файлы непосредственно в указанном каталоге, а подкаталоги игнорируются.

Дополнительные аспекты и рекомендации

Следуя этим рекомендациям и используя предложенный подход, вы сможете эффективно создавать ZIP-архивы с требуемой вложенной структурой каталогов в вашей конфигурации 1С.

← К списку