Разработка и Конфигурация · 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Убедитесь, что файл архива существует и доступен по указанному пути
- 2Создайте объект ЧтениеZipФайла с полным именем файла
- 3Создайте каталог назначения командой СоздатьКаталог
- 4Вызовите ИзвлечьВсе с нужным режимом восстановления путей
- 5Закройте архив методом Закрыть
- 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). Проверьте права на папку и что файлы не заняты другим процессом.
- Нехватка места — распаковка прерывается на середине, часть файлов остаётся. Всегда очищайте временный каталог перед повторной попыткой.
Безопасность при распаковке чужих архивов
Архив, полученный извне (по почте, через API, от контрагента), нельзя распаковывать вслепую. Известна уязвимость класса «Zip Slip»: элемент архива может содержать путь вида ..\..\..\Windows\system32\..., и при наивной распаковке файл запишется за пределы целевого каталога. Перед извлечением проверяйте, что Имя элемента не содержит последовательностей «..» и абсолютных путей.
Дополнительные меры: распаковывайте в отдельный временный каталог, ограничивайте суммарный размер извлекаемых данных (защита от «zip-бомб» — архивов, разворачивающихся в десятки гигабайт), а исполняемые файлы и скрипты из архива не запускайте автоматически. После обработки временный каталог удаляйте, чтобы не копить мусор на сервере.
Как проверить результат распаковки
Совпадает с количеством элементов архива (ЧтениеZip.Элементы.Количество())
Файлов меньше — часть не извлеклась или перезаписалась из-за совпадающих имён
Русские и специальные символы читаются корректно
Крякозябры — архив создан без UTF-8-флага кодировки
Файл открывается и парсится без ошибок
Ошибка чтения — архив был повреждён при передаче
Каталог очищен или удалён
Копятся старые распаковки, растёт занятое место
Альтернативы: когда встроенных средств недостаточно
Если формат не поддерживается (RAR, 7z, AES-шифрование, многотомные архивы) или требуется работа с архивом в памяти без записи на диск, вариантов несколько. Самый распространённый — вызов консольной версии 7-Zip через ЗапуститьПриложение() с параметрами командной строки: утилита бесплатна, понимает десятки форматов и позволяет задать пароль. На Windows возможна работа через COM-объект Shell.Application, но этот способ медленный и нестабилен под сервером. Для Linux-серверов доступны системные утилиты unzip и 7z через КомандаСистемы().
Способы распаковки в 1С
Подходит для обычных ZIP без AES-шифрования. Кроссплатформенно, не требует установки компонентов. Не читает RAR, 7z и многотомные архивы.
Универсальный вариант для любых форматов и AES-паролей. Требует установки утилиты на сервере и аккуратного экранирования путей и паролей в команде.
Работает без установки ПО, но только под 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Файла: создайте его конструктором с именем будущего файла, добавьте файлы методом Добавить с указанием режима сжатия и сохраните методом Записать. Поддерживаются уровни сжатия, пароль и добавление целых каталогов.