Читайте дальше...
Создание ZIP-архива и добавление файлов
// Создание нового ZIP-архива и добавление в него файлов
Процедура СоздатьZipАрхив()
// Путь к создаваемому архиву
ПутьКАрхиву = "C:\Temp\МойАрхив.zip";
// Создаем новый ZIP-архив
ZipАрхив = Новый ZipЗапись(ПутьКАрхиву);
// Добавляем текстовый файл из строки
ZipАрхив.Добавить("Приветствие.txt", "Здравствуй, мир!" + Символы.ПС + "Это тестовое содержимое");
// Добавляем файл из существующего файла на диске
// (предварительно создадим тестовый файл)
ТестовыйФайл = "C:\Temp\test.txt";
ЗаписьТекста = Новый ЗаписьТекста(ТестовыйФайл, КодировкаТекста.UTF8);
ЗаписьТекста.ЗаписатьСтроку("Тестовые данные для архива");
ЗаписьТекста.Закрыть();
ZipАрхив.Добавить("test.txt", ТестовыйФайл);
// Добавляем файл с указанием кодировки имени в архиве
ZipАрхив.Добавить("Документ.docx", "C:\Temp\document.docx", КодировкаТекста.UTF8);
// Завершаем запись архива
ZipАрхив.Записать();
ZipАрхив.Закрыть();
Сообщить("ZIP-архив создан: " + ПутьКАрхиву);
// Проверяем существование архива
Если ФайлСуществует(ПутьКАрхиву) Тогда
Инфо = Новый ИнформацияОФайле(ПутьКАрхиву);
Сообщить("Размер архива: " + Инфо.Размер + " байт");
КонецЕсли;
КонецПроцедуры
Чтение содержимого ZIP-архива и извлечение файлов
// Открытие ZIP-архива, просмотр содержимого и извлечение файлов
Процедура ЧтениеZipАрхива()
ПутьКАрхиву = "C:\Temp\МойАрхив.zip";
ПутьДляИзвлечения = "C:\Temp\Extracted\";
// Проверяем существование архива
Если Не ФайлСуществует(ПутьКАрхиву) Тогда
Сообщить("Архив не найден: " + ПутьКАрхиву);
Возврат;
КонецЕсли;
// Создаем каталог для извлечения, если его нет
Если Не КаталогСуществует(ПутьДляИзвлечения) Тогда
СоздатьКаталог(ПутьДляИзвлечения);
КонецЕсли;
// Открываем ZIP-архив для чтения
ЧтениеZip = Новый ZipЧтение(ПутьКАрхиву);
// Получаем список файлов в архиве
ФайлыВАрхиве = ЧтениеZip.Элементы;
Сообщить("Содержимое архива '" + ПутьКАрхиву + "':");
Сообщить("Всего элементов: " + ФайлыВАрхиве.Количество());
// Перебираем все элементы архива
Для Каждого Элемент Из ФайлыВАрхиве Цикл
Если Элемент.ЭтоFolder Тогда
Сообщить("[ПАПКА] " + Элемент.Имя + " (размер: " + Элемент.Размер + ")");
Иначе
Сообщить("[ФАЙЛ] " + Элемент.Имя + " (размер: " + Элемент.Размер + " байт)");
// Извлекаем файл
ПутьИзвлеченногоФайла = ПутьДляИзвлечения + Элемент.Имя;
ЧтениеZip.Извлечь(Элемент, ПутьИзвлеченногоФайла);
Сообщить(" -> извлечен в: " + ПутьИзвлеченногоФайла);
КонецЕсли;
КонецЦикла;
// Закрываем архив
ЧтениеZip.Закрыть();
Сообщить("Извлечение завершено");
КонецПроцедуры
Добавление файлов с сохранением структуры папок
// Добавление файлов в ZIP-архив с сохранением
// иерархической структуры каталогов
Процедура ДобавитьФайлСоСтруктуройПапок()
ПутьКАрхиву = "C:\Temp\СтруктурированныйАрхив.zip";
КорневаяПапка = "C:\Temp\Source\";
// Создаем тестовую структуру папок и файлов
СоздатьТестовуюСтруктуру(КорневаяПапка);
// Создаем архив
ZipАрхив = Новый ZipЗапись(ПутьКАрхиву);
// Функция рекурсивного обхода папок и добавления файлов
Процедура ДобавитьПапкуВАрхив(ПутьПапки, ОтносительныйПуть, ZipАрхив)
НайтиФайлы = Новый НайтиФайлы;
НайтиФайлы.НайтиФайлы(ПутьПапки, "*", Истина);
Для Каждого Файл Из НайтиФайлы.Файлы Цикл
// Формируем путь внутри архива
ПутьВАрхиве = ОтносительныйПуть + Файл.Имя;
ZipАрхив.Добавить(ПутьВАрхиве, Файл.ПолноеИмя);
Сообщить("Добавлен файл: " + ПутьВАрхиве);
КонецЦикла;
// Обрабатываем вложенные папки
НайтиПапки = Новый НайтиФайлы;
НайтиПапки.НайтиФайлы(ПутьПапки, "*", Истина);
Для Каждого Папка Из НайтиПапки.Папки Цикл
НовыйОтносительныйПуть = ОтносительныйПуть + Папка.Имя + "/";
ДобавитьПапкуВАрхив(Папка.ПолноеИмя, НовыйОтносительныйПуть, ZipАрхив);
КонецЦикла;
КонецПроцедуры
// Запускаем обход
ДобавитьПапкуВАрхив(КорневаяПапка, "", ZipАрхив);
// Завершаем запись
ZipАрхив.Записать();
ZipАрхив.Закрыть();
Сообщить("Архив со структурой создан: " + ПутьКАрхиву);
КонецПроцедуры
Процедура СоздатьТестовуюСтруктуру(КорневаяПапка)
Если Не КаталогСуществует(КорневаяПапка + "Папка1\") Тогда
СоздатьКаталог(КорневаяПапка + "Папка1\");
КонецЕсли;
Запись = Новый ЗаписьТекста(КорневаяПапка + "Папка1\файл1.txt", КодировкаТекста.UTF8);
Запись.ЗаписатьСтроку("Содержимое файла 1");
Запись.Закрыть();
Если Не КаталогСуществует(КорневаяПапка + "Папка1\Папка2\") Тогда
СоздатьКаталог(КорневаяПапка + "Папка1\Папка2\");
КонецЕсли;
Запись = Новый ЗаписьТекста(КорневаяПапка + "Папка1\Папка2\файл2.txt", КодировкаТекста.UTF8);
Запись.ЗаписатьСтроку("Содержимое файла 2");
Запись.Закрыть();
КонецПроцедуры
Обработка ошибок при работе с ZIP-архивами
// Безопасная работа с ZIP-архивами с обработкой возможных ошибок
Процедура БезопаснаяРаботаСZip()
ПутьКАрхиву = "C:\Temp\НесуществующийАрхив.zip";
ПутьДляИзвлечения = "C:\Temp\Extract\";
// Проверка существования архива перед открытием
Если Не ФайлСуществует(ПутьКАрхиву) Тогда
Сообщить("Ошибка: файл не существует - " + ПутьКАрхиву);
Возврат;
КонецЕсли;
// Создание каталога для извлечения с проверкой
Если Не КаталогСуществует(ПутьДляИзвлечения) Тогда
Попытка
СоздатьКаталог(ПутьДляИзвлечения);
Исключение
Сообщить("Не удалось создать каталог: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
КонецЕсли;
// Открытие архива с обработкой ошибок
Попытка
ЧтениеZip = Новый ZipЧтение(ПутьКАрхиву);
Исключение
Сообщить("Ошибка открытия архива: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Проверка, что архив не поврежден
Попытка
ФайлыВАрхиве = ЧтениеZip.Элементы;
Если ФайлыВАрхиве.Количество() = 0 Тогда
Сообщить("Архив пуст");
КонецЕсли;
Исключение
Сообщить("Ошибка чтения содержимого архива: " + ОписаниеОшибки());
ЧтениеZip.Закрыть();
Возврат;
КонецПопытки;
// Извлечение файлов с проверкой свободного места
СвободноеМесто = ВычислитьСвободноеМесто(ПутьДляИзвлечения);
ОбщийРазмер = 0;
Для Каждого Элемент Из ФайлыВАрхиве Цикл
Если Не Элемент.ЭтоFolder Тогда
ОбщийРазмер = ОбщийРазмер + Элемент.Размер;
КонецЕсли;
КонецЦикла;
Если ОбщийРазмер > СвободноеМесто Тогда
Сообщить("Недостаточно свободного места на диске. Требуется: " +
Строка(ОбщийРазмер) + " байт, доступно: " + Строка(СвободноеМесто) + " байт");
ЧтениеZip.Закрыть();
Возврат;
КонецЕсли;
// Извлечение файлов
КоличествоИзвлеченных = 0;
Для Каждого Элемент Из ФайлыВАрхиве Цикл
Если Не Элемент.ЭтоFolder Тогда
Попытка
ПутьИзвлечения = ПутьДляИзвлечения + Элемент.Имя;
ЧтениеZip.Извлечь(Элемент, ПутьИзвлечения);
КоличествоИзвлеченных = КоличествоИзвлеченных + 1;
Сообщить("Извлечен: " + Элемент.Имя);
Исключение
Сообщить("Ошибка извлечения файла " + Элемент.Имя + ": " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
ЧтениеZip.Закрыть();
Сообщить("Извлечено файлов: " + Строка(КоличествоИзвлеченных) +
" из " + Строка(ФайлыВАрхиве.Количество()));
КонецПроцедуры
Функция ВычислитьСвободноеМесто(Путь)
// Упрощенная эмуляция получения свободного места
Возврат 1000000000; // 1 ГБ (в реальном коде нужно использовать API системы)
КонецФункции
Создание ZIP-архива из таблицы файлов (пакетная обработка)
// Пакетное добавление файлов в архив из таблицы значений
Процедура СоздатьАрхивИзТаблицыФайлов()
// Создаем таблицу с перечнем файлов для архивации
ТаблицаФайлов = Новый ТаблицаЗначений;
ТаблицаФайлов.Колонки.Добавить("ПутьКФайлу");
ТаблицаФайлов.Колонки.Добавить("ИмяВАрхиве");
ТаблицаФайлов.Колонки.Добавить("ПапкаВАрхиве");
// Заполняем тестовыми данными
Для Инд = 1 По 5 Цикл
ИмяФайла = "C:\Temp\file" + Строка(Инд) + ".txt";
Запись = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.UTF8);
Запись.ЗаписатьСтроку("Содержимое файла " + Строка(Инд));
Запись.Закрыть();
НоваяСтрока = ТаблицаФайлов.Добавить();
НоваяСтрока.ПутьКФайлу = ИмяФайла;
НоваяСтрока.ИмяВАрхиве = "file" + Строка(Инд) + ".txt";
НоваяСтрока.ПапкаВАрхиве = "Документы/Загрузки/";
КонецЦикла;
// Создаем архив
ПутьКАрхиву = "C:\Temp\АрхивИзТаблицы_" + Формат(ТекущаяДата(), "ДФ=yyyyMMddHHmmss") + ".zip";
ZipАрхив = Новый ZipЗапись(ПутьКАрхиву);
// Добавляем файлы из таблицы
Для Каждого СтрокаФайла Из ТаблицаФайлов Цикл
// Проверяем существование файла
Если ФайлСуществует(СтрокаФайла.ПутьКФайлу) Тогда
// Формируем полный путь внутри архива
ПолныйПутьВАрхиве = СтрокаФайла.ПапкаВАрхиве + СтрокаФайла.ИмяВАрхиве;
ZipАрхив.Добавить(ПолныйПутьВАрхиве, СтрокаФайла.ПутьКФайлу);
Сообщить("Добавлен: " + СтрокаФайла.ПутьКФайлу + " -> " + ПолныйПутьВАрхиве);
Иначе
Сообщить("Файл не найден: " + СтрокаФайла.ПутьКФайлу);
КонецЕсли;
КонецЦикла;
// Завершаем запись
Попытка
ZipАрхив.Записать();
ZipАрхив.Закрыть();
Сообщить("Архив успешно создан: " + ПутьКАрхиву);
Исключение
Сообщить("Ошибка при создании архива: " + ОписаниеОшибки());
КонецПопытки;
// Получаем информацию о созданном архиве
Если ФайлСуществует(ПутьКАрхиву) Тогда
Инфо = Новый ИнформацияОФайле(ПутьКАрхиву);
Сообщить("Размер архива: " + Инфо.Размер + " байт (" +
Окр(Инфо.Размер / 1024, 2) + " КБ)");
КонецЕсли;
КонецПроцедуры
Архивация с разбивкой на тома (многотомный архив)
// Создание ZIP-архива с автоматическим разбиением на части заданного размера
Процедура СоздатьМноготомныйZipАрхив()
// Путь к исходному файлу (большой файл)
БольшойФайл = "C:\Temp\BigFile.dat";
РазмерПорции = 1024 * 1024; // 1 МБ
// Создаем тестовый большой файл
Запись = Новый ЗаписьТекста(БольшойФайл, КодировкаТекста.UTF8);
Для Инд = 1 По 1000 Цикл
Запись.ЗаписатьСтроку("Строка с данными номер " + Строка(Инд) +
". Здесь много текста для увеличения размера файла.");
КонецЦикла;
Запись.Закрыть();
// Создаем архив
БазовоеИмяАрхива = "C:\Temp\MultipartArchive.zip";
НомерТома = 1;
ТекущийРазмер = 0;
ZipАрхив = Неопределено;
// Функция открытия нового тома
Процедура ОткрытьНовыйТом(БазовоеИмя, НомерТома)
ИмяТома = СтрЗаменить(БазовоеИмя, ".zip", ".part" + Строка(НомерТома) + ".zip");
Возврат Новый ZipЗапись(ИмяТома);
КонецПроцедуры
// Открываем первый том
ТекущийАрхив = ОткрытьНовыйТом(БазовоеИмяАрхива, НомерТома);
// Добавляем файл по частям (эмуляция)
// В реальном коде нужно читать исходный файл порциями
Для Порция = 1 По 5 Цикл
// Добавляем в текущий том кусок данных
ИмяВАрхиве = "BigFile_part" + Строка(Порция) + ".dat";
Данные = "Тестовые данные для порции " + Строка(Порция);
ТекущийАрхив.Добавить(ИмяВАрхиве, Данные);
ТекущийРазмер = ТекущийРазмер + СтрДлина(Данные);
// Если размер превысил лимит, создаем новый том
Если ТекущийРазмер >= РазмерПорции Тогда
ТекущийАрхив.Записать();
ТекущийАрхив.Закрыть();
НомерТома = НомерТома + 1;
ТекущийАрхив = ОткрытьНовыйТом(БазовоеИмяАрхива, НомерТома);
ТекущийРазмер = 0;
Сообщить("Создан том #" + Строка(НомерТома - 1));
КонецЕсли;
КонецЦикла;
// Закрываем последний том
Если ТекущийАрхив <> Неопределено Тогда
ТекущийАрхив.Записать();
ТекущийАрхив.Закрыть();
Сообщить("Создан последний том #" + Строка(НомерТома));
КонецЕсли;
// Информация о созданных томах
Сообщить("Создано томов: " + Строка(НомерТома));
Для Ном = 1 По НомерТома Цикл
ИмяТома = СтрЗаменить(БазовоеИмяАрхива, ".zip", ".part" + Строка(Ном) + ".zip");
Если ФайлСуществует(ИмяТома) Тогда
Инфо = Новый ИнформацияОФайле(ИмяТома);
Сообщить("Том " + Строка(Ном) + ": " + Инфо.Размер + " байт");
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Сжатие каталога с помощью рекурсивного обхода
// Полное сжатие выбранного каталога со всем содержимым
Процедура СжатьКаталогВZip(ПутьКаталога, ПутьАрхива = "")
// Если путь архива не указан, создаем рядом с каталогом
Если ПутьАрхива = "" Тогда
ПутьАрхива = КаталогИзвлечения(ПутьКаталога) + ИмяКаталога(ПутьКаталога) + ".zip";
КонецЕсли;
// Проверяем существование каталога
Если Не КаталогСуществует(ПутьКаталога) Тогда
Сообщить("Каталог не найден: " + ПутьКаталога);
Возврат;
КонецЕсли;
// Создаем архив
Попытка
ZipАрхив = Новый ZipЗапись(ПутьАрхива);
// Рекурсивно добавляем все файлы
ДобавитьКаталогВZip(ПутьКаталога, ZipАрхив, "");
ZipАрхив.Записать();
ZipАрхив.Закрыть();
Сообщить("Каталог '" + ПутьКаталога + "' успешно сжат в '" + ПутьАрхива + "'");
Исключение
Сообщить("Ошибка при сжатии каталога: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура ДобавитьКаталогВZip(ПутьКаталога, ZipАрхив, ОтносительныйПуть)
// Обрабатываем файлы в текущем каталоге
НайтиФайлы = Новый НайтиФайлы;
НайтиФайлы.НайтиФайлы(ПутьКаталога, "*", Истина);
Для Каждого Файл Из НайтиФайлы.Файлы Цикл
// Формируем путь файла внутри архива
ПутьВАрхиве = ОтносительныйПуть + Файл.Имя;
// Добавляем файл в архив
ZipАрхив.Добавить(ПутьВАрхиве, Файл.ПолноеИмя);
Сообщить("Добавлен файл: " + ПутьВАрхиве);
КонецЦикла;
// Обрабатываем вложенные каталоги
НайтиПапки = Новый НайтиФайлы;
НайтиПапки.НайтиФайлы(ПутьКаталога, "*", Истина);
Для Каждого Папка Из НайтиПапки.Папки Цикл
// Рекурсивно обрабатываем каждую вложенную папку
НовыйОтносительныйПуть = ОтносительныйПуть + Папка.Имя + "/";
ДобавитьКаталогВZip(Папка.ПолноеИмя, ZipАрхив, НовыйОтносительныйПуть);
КонецЦикла;
КонецПроцедуры
// Пример использования
Процедура ПримерСжатияКаталога()
// Создаем тестовый каталог с файлами
ТестовыйКаталог = "C:\Temp\TestCatalog\";
Если Не КаталогСуществует(ТестовыйКаталог) Тогда
СоздатьКаталог(ТестовыйКаталог);
КонецЕсли;
Для Инд = 1 По 3 Цикл
ИмяФайла = ТестовыйКаталог + "file" + Строка(Инд) + ".txt";
Запись = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.UTF8);
Запись.ЗаписатьСтроку("Содержимое файла " + Строка(Инд));
Запись.Закрыть();
КонецЦИКЛА;
// Сжимаем каталог
СжатьКаталогВZip(ТестовыйКаталог);
КонецПроцедуры
Примечания
// Важные особенности работы с ZIP-архивами в 1С:
// 1. Для работы с ZIP-архивами используются объекты ZipЗапись (создание) и ZipЧтение (чтение)
// 2. Обязательно закрывайте архив методами Записать() (для ZipЗапись) и Закрыть() (для обоих типов)
// 3. Метод Добавить() позволяет добавлять файлы как из существующих файлов, так и из строки данных
// 4. При чтении архива свойство Элементы возвращает коллекцию элементов (файлов и папок)
// 5. Проверяйте наличие архива и каталогов перед операциями во избежание ошибок
// 6. Используйте конструкцию Попытка...Исключение...КонецПопытки для обработки ошибок доступа
// 7. Вложенные папки в архиве создаются автоматически при указании пути с разделителями
// 8. Для рекурсивного добавления целых каталогов используйте НайтиФайлы и обход в глубину
// 9. ZIP-архивы в 1С не поддерживают шифрование и комментарии
// 10. Размер добавляемого файла ограничен доступной памятью и свободным местом на диске
// 11. При работе с большими файлами используйте пакетную обработку и контроль свободного места
// 12. Метод Извлечь() может перезаписывать существующие файлы без предупреждения - учитывайте это








