Потоковая работа с архивами

Запись ZIP-архива в поток

Для записи архива используется тип ЗаписьZip. Архив будет записываться в какой-либо поток, предназначенный для записи. Такой поток, например, можно получить из значения типа Файл следующим образом: Файл.ОткрытьПотокЗаписи(). Также для архива можно указать пароль, уровень сжатия и комментарий.

Для добавления файла в создаваемый архив предназначен метод Добавить() типа ЗаписьZip. При добавлении файла в архив следует помнить о том, как в архиве формируется иерархия файлов. Параметр ПутьВАрхиве метода Добавить() позволяет указать путь к добавляемому файлу. Если указать в этом параметре полный путь к добавляемому файлу — в архиве будет сохранен именно он. Если требуется указать относительный путь к файлу — необходимо самостоятельно удалить фрагмент пути от корня файловой системы до нужного уровня.

Далее будет приведен пример добавления в архив всех файлов с расширением .xml в каталоге Documents домашнего каталога текущего пользователя (с обходом всех подкаталогов). Файлы будут сохраняться в архиве по относительным путям. Корневым каталогом архива будет каталог Documents.
метод ДобавлениеФайловВАрхив()
    пер Источник = новый Файл(Файлы.ПолучитьДомашнийКаталог().Путь + "\\Documents")
    пер ИмяАрхива = новый Файл(Источник.Путь + "\\xml-files.zip")
    пер Писатель = новый ЗаписьZip(ИмяАрхива.ОткрытьПотокЗаписи())
    для Файл из Источник.Дочерние
    	ДобавитьРекурсивно(Писатель, Файл, ИмяАрхива.Каталог.Путь)
    ;
    Писатель.Записать()
;
    		
метод ДобавитьРекурсивно(ПотокАрхива: ЗаписьZip, Источник: Файл, КорневойКаталог: Строка)
    если Источник.ЭтоФайл() и Источник.Расширение == "xml"
    	ПотокАрхива.Добавить(Источник.ОткрытьПотокЧтения(), Источник.Путь.Заменить(КорневойКаталог, ""))
    ;
    для Файл из Источник.Дочерние
    	ДобавитьРекурсивно(ПотокАрхива, Файл, КорневойКаталог)
    ;
;

В данном примере формирование относительного пути в архиве происходит при выполнении следующей операции: Источник.Путь.Заменить(КорневойКаталог, "").

Чтение ZIP-архива из потока

Для чтения ZIP-архива используется тип ЧтениеZip. Общая схема работы с данным типом подобна записи архива: для файла с архивом получается поток чтения; затем создается экземпляр ЧтениеZip, который читает данные из потока чтения; затем происходит получение содержимого архива. Если имена файлов внутри архива сохранены не в кодировке UTF-8, вы можете задать параметр КодировкаИменФайлов для указания нужной кодировки, чтобы избежать появления нечитаемых символов в именах файлов и путей к ним.

Подробнее о поддерживаемых кодировках

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

Следующий пример ищет в каталоге, который задается переменной ГдеИщем, все ZIP-архивы и извлекает информацию о файлах внутри каждого архива.
метод ПоискАрхивовВКаталоге()
    пер ГдеИщем = "<путь к каталогу с zip-файлами>"
    пер СписокФайлов = Файлы.Найти(ГдеИщем, новый НастройкиПоискаФайлов().ИмяСодержит(".zip"))
    пер КодировкаИменФайлов = Кодировка.Windows1251
    для Файл из СписокФайлов
        пер Архив = новый ЧтениеZip(Файл.ОткрытьПотокЧтения(), КодировкаИменФайлов = КодировкаИменФайлов)
        // Обход содержимого архива
        пока Архив.Следующий()
            // Получение текущего элемента архива
            пер Элемент = Архив.ПолучитьЭлемент()
            // Получение информации об элементе
            // Имя элемента
            пер Имя = Элемент.Имя
            // Путь к элементу в архиве
            пер Путь = Элемент.ПутьВАрхиве
            // Проверка, является ли элемент каталогом
            пер Каталог = Элемент.ЭтоКаталог()
        ;
    ;
;