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

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

Как в 1С разархивировать ZIP-архив

Как распаковать ZIP-архив в 1С: встроенные объекты ЧтениеZipФайла и ЗаписьZipФайла, примеры кода, обработка ошибок, работа с паролями и большими файлами.

ZIP-архивы постоянно встречаются в работе с 1С: обмен с сайтами и госуслугами, выгрузки из банков, пакеты электронных документов, поставки обновлений. Платформа 1С:Предприятие умеет работать с ZIP без сторонних программ — для этого во встроенном языке есть объекты ЧтениеZipФайла и ЗаписьZipФайла. Они доступны и на сервере, и на клиенте (в тонком и толстом клиенте), поэтому распаковку можно встроить прямо в бизнес-логику конфигурации.

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

Какие инструменты для ZIP есть в платформе 1С

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

Важное ограничение: встроенные объекты поддерживают только классический формат ZIP (методы сжатия Deflate и Store). Архивы RAR, 7z, tar.gz платформа напрямую не открывает — для них потребуется внешняя утилита, вызываемая через командную строку, или COM-объект. Также штатные средства не читают многотомные (разбитые на части) архивы.

Базовый код: распаковать архив целиком

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

ЧтениеZip = Новый ЧтениеZipФайла("C:\Обмен\data.zip");

КаталогНазначения = "C:\Обмен\Распаковано\";

СоздатьКаталог(КаталогНазначения);

ЧтениеZip.ИзвлечьВсе(КаталогНазначения,

РежимВосстановленияПутейФайловZIP.Восстанавливать);

ЧтениеZip.Закрыть();

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

Порядок распаковки
  1. 1
    Убедитесь, что файл архива существует и доступен по указанному пути
  2. 2
    Создайте объект ЧтениеZipФайла с полным именем файла
  3. 3
    Создайте каталог назначения командой СоздатьКаталог
  4. 4
    Вызовите ИзвлечьВсе с нужным режимом восстановления путей
  5. 5
    Закройте архив методом Закрыть
  6. 6
    Проверьте, что количество файлов в каталоге совпадает с числом элементов архива

Извлечение отдельных файлов и фильтрация содержимого

Не всегда нужен весь архив. Например, из выгрузки обмена с сайтом может требоваться только XML с заказами, а картинки товаров — пропустить. Для этого перебирают коллекцию Элементы и извлекают выборочно.

ЧтениеZip = Новый ЧтениеZipФайла(ИмяАрхива);

Для Каждого Элемент Из ЧтениеZip.Элементы Цикл

Если СтрЗаканчиваетсяНа(НРег(Элемент.Имя), ".xml") Тогда

ЧтениеZip.Извлечь(Элемент, КаталогНазначения,

РежимВосстановленияПутейФайловZIP.НеВосстанавливать);

КонецЕсли;

КонецЦикла;

ЧтениеZip.Закрыть();

У каждого элемента доступны полезные свойства: Имя, ИмяБезПути, РазмерНесжатого, РазмерСжатого, ВремяИзменения. По ним удобно строить проверки: например, отказаться от распаковки, если суммарный несжатый размер превышает свободное место на диске, или пропускать файлы старше определённой даты.

Как узнать содержимое архива без распаковки

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

Работа с паролем и шифрованными архивами

Если архив защищён паролем, он передаётся вторым параметром конструктора:

ЧтениеZip = Новый ЧтениеZipФайла("C:\Обмен\secure.zip", "Пароль123");

Здесь есть важное ограничение: платформа поддерживает классическое шифрование ZIP (ZipCrypto), но не поддерживает современное AES-шифрование, которое по умолчанию используют, например, 7-Zip и WinRAR при создании защищённых архивов. Если архив зашифрован AES, попытка чтения завершится ошибкой даже с верным паролем. В таком случае распаковку выполняют внешней утилитой через ЗапуститьПриложение() или КомандаСистемы().

Обработка ошибок и типичные проблемы

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

Попытка

ЧтениеZip = Новый ЧтениеZipФайла(ИмяАрхива);

ЧтениеZip.ИзвлечьВсе(КаталогНазначения);

ЧтениеZip.Закрыть();

Исключение

ЗаписьЖурналаРегистрации("Распаковка ZIP",

УровеньЖурналаРегистрации.Ошибка,,,

ОписаниеОшибки());

КонецПопытки;

Наиболее частые сбои:

  • «Файл не является архивом ZIP» — файл повреждён при передаче, недокачан или это вообще не ZIP (например, переименованный RAR). Проверьте размер файла и первые байты: у ZIP-файла они начинаются с сигнатуры «PK».
  • Крякозябры в именах файлов — архив создан программой, записавшей имена не в UTF-8. Платформа интерпретирует имена по флагу кодировки в архиве; если флаг не выставлен, русские имена искажаются. Решение — распаковать внешним архиватором или пересоздать архив корректной программой.
  • Ошибка доступа — каталог назначения недоступен для записи учётной записи, под которой работает сервер 1С (обычно USR1CV8). Проверьте права на папку и что файлы не заняты другим процессом.
  • Нехватка места — распаковка прерывается на середине, часть файлов остаётся. Всегда очищайте временный каталог перед повторной попыткой.
Типичные ошибки
01
Распаковка без проверки существования файла архива — получаете невнятную ошибку платформы вместо понятного сообщения
02
Игнорирование режима восстановления путей: файлы с одинаковыми именами из разных папок архива затирают друг друга
03
Отсутствие вызова Закрыть() — файл архива остаётся заблокированным до конца сеанса
04
Попытка открыть AES-зашифрованный архив штатными средствами — ошибка даже с правильным паролем
05
Распаковка архива из недоверенного источника без проверки имён файлов — риск извлечения вредоносного содержимого

Безопасность при распаковке чужих архивов

Архив, полученный извне (по почте, через API, от контрагента), нельзя распаковывать вслепую. Известна уязвимость класса «Zip Slip»: элемент архива может содержать путь вида ..\..\..\Windows\system32\..., и при наивной распаковке файл запишется за пределы целевого каталога. Перед извлечением проверяйте, что Имя элемента не содержит последовательностей «..» и абсолютных путей.

Дополнительные меры: распаковывайте в отдельный временный каталог, ограничивайте суммарный размер извлекаемых данных (защита от «zip-бомб» — архивов, разворачивающихся в десятки гигабайт), а исполняемые файлы и скрипты из архива не запускайте автоматически. После обработки временный каталог удаляйте, чтобы не копить мусор на сервере.

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

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

Количество файлов в каталоге назначения
Норма

Совпадает с количеством элементов архива (ЧтениеZip.Элементы.Количество())

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

Файлов меньше — часть не извлеклась или перезаписалась из-за совпадающих имён

Имена извлечённых файлов
Норма

Русские и специальные символы читаются корректно

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

Крякозябры — архив создан без UTF-8-флага кодировки

Содержимое ключевого файла (XML, CSV)
Норма

Файл открывается и парсится без ошибок

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

Ошибка чтения — архив был повреждён при передаче

Временные каталоги после обработки
Норма

Каталог очищен или удалён

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

Копятся старые распаковки, растёт занятое место

Альтернативы: когда встроенных средств недостаточно

Если формат не поддерживается (RAR, 7z, AES-шифрование, многотомные архивы) или требуется работа с архивом в памяти без записи на диск, вариантов несколько. Самый распространённый — вызов консольной версии 7-Zip через ЗапуститьПриложение() с параметрами командной строки: утилита бесплатна, понимает десятки форматов и позволяет задать пароль. На Windows возможна работа через COM-объект Shell.Application, но этот способ медленный и нестабилен под сервером. Для Linux-серверов доступны системные утилиты unzip и 7z через КомандаСистемы().

Способы распаковки в 1С

ЧтениеZipФайла (штатный объект)

Подходит для обычных ZIP без AES-шифрования. Кроссплатформенно, не требует установки компонентов. Не читает RAR, 7z и многотомные архивы.

Внешняя утилита 7-Zip через командную строку

Универсальный вариант для любых форматов и AES-паролей. Требует установки утилиты на сервере и аккуратного экранирования путей и паролей в команде.

COM-объект Shell.Application

Работает без установки ПО, но только под Windows, медленно и ненадёжно в серверном контексте. Подходит разве что для разовых интерактивных операций.

Практический пример: обработка архива обмена

Соберём типовой сценарий целиком: получили архив из каталога обмена, распаковали во временную папку, нашли XML-файл и передали его дальше, затем убрали за собой.

ВременныйКаталог = КаталогВременныхФайлов() + "zip_" + Строка(Новый УникальныйИдентификатор) + "\";

СоздатьКаталог(ВременныйКаталог);

Попытка

ЧтениеZip = Новый ЧтениеZipФайла(ИмяАрхива);

Для Каждого Элемент Из ЧтениеZip.Элементы Цикл

Если СтрНайти(Элемент.Имя, "..") > 0 Тогда

ВызватьИсключение "Небезопасный путь в архиве: " + Элемент.Имя;

КонецЕсли;

КонецЦикла;

ЧтениеZip.ИзвлечьВсе(ВременныйКаталог,

РежимВосстановленияПутейФайловZIP.Восстанавливать);

ЧтениеZip.Закрыть();

НайденныеФайлы = НайтиФайлы(ВременныйКаталог, "*.xml", Истина);

Если НайденныеФайлы.Количество() = 0 Тогда

ВызватьИсключение "В архиве нет XML-файлов";

КонецЕсли;

// дальнейшая обработка НайденныеФайлы[0].ПолноеИмя

Исключение

УдалитьФайлы(ВременныйКаталог);

ВызватьИсключение;

КонецПопытки;

УдалитьФайлы(ВременныйКаталог);

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

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

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

Штатный объект ЧтениеZipФайла закрывает большинство задач распаковки ZIP в 1С: открыть архив, извлечь всё или выборочно, закрыть. Проверяйте пути элементов, обрабатывайте ошибки через Попытка/Исключение, очищайте временные каталоги. Для RAR, 7z и AES-шифрования используйте внешний архиватор через командную строку.

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

Можно ли распаковать ZIP в 1С без записи на диск, прямо в память?

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

Почему при распаковке русские имена файлов превращаются в крякозябры?

Архив создан программой, которая записала имена в локальной кодировке без установки флага UTF-8. Платформа 1С ориентируется на этот флаг, поэтому имена искажаются. Решения: попросить источник пересоздать архив современным архиватором, распаковать внешней утилитой (7-Zip корректно подбирает кодировку) или переименовать файлы после извлечения, если известна исходная кодировка.

Как распаковать архив, защищённый паролем AES?

Встроенный ЧтениеZipФайла поддерживает только классическое шифрование ZipCrypto и с AES-архивами не работает. Используйте консольную версию 7-Zip: вызовите её через ЗапуститьПриложение с параметрами вида x -pПароль -oКаталог ИмяАрхива и дождитесь завершения процесса.

Чем ограничен размер архива, который может обработать 1С?

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

Как распаковать архив на сервере 1С под Linux?

Объект ЧтениеZipФайла кроссплатформен и работает под Linux без изменений кода — учитывайте только разделитель путей «/» и регистрочувствительность файловой системы. Если нужен внешний архиватор, вызывайте unzip или 7z через КомандаСистемы.

Можно ли из 1С не только распаковать, но и создать ZIP-архив?

Да, для этого служит объект ЗаписьZipФайла: создайте его конструктором с именем будущего файла, добавьте файлы методом Добавить с указанием режима сжатия и сохраните методом Записать. Поддерживаются уровни сжатия, пароль и добавление целых каталогов.