Работа с ZIP-архивами в Java: полное руководство по java.util.zip

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с ZIP-архивами в Java: полное руководство

В современной разработке на Java часто возникает необходимость упаковывать и распаковывать файлы. ZIP — один из самых популярных форматов сжатия, поддерживаемый стандартной библиотекой Java. Встроенный пакет java.util.zip предоставляет все необходимые инструменты для работы с ZIP-архивами без установки сторонних зависимостей.

Основные классы пакета java.util.zip

Пакет java.util.zip включает несколько ключевых классов для работы с архивами:

  • ZipOutputStream — для создания ZIP-архивов и записи в них файлов
  • ZipInputStream — для чтения содержимого ZIP-архивов
  • ZipEntry — представляет отдельную запись (файл или директорию) внутри архива
  • ZipFile — для прямого доступа к записям архива по имени
  • Deflater/Inflater — низкоуровневые классы для сжатия/распаковки данных

Создание ZIP-архива

Для создания архива используется ZipOutputStream. Каждый добавляемый файл представляется как ZipEntry. Рассмотрим пример, который упаковывает несколько файлов в один архив:

import java.io.*;
import java.util.zip.*;

public class CreateZipExample {
    public static void main(String[] args) {
        // Массив файлов для архивации
        String[] sourceFiles = {"file1.txt", "file2.txt", "image.png"};
        String zipFileName = "archive.zip";

        try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFileName))) {
            byte[] buffer = new byte[1024];

            for (String filePath : sourceFiles) {
                File file = new File(filePath);
                // Создаем запись в архиве
                ZipEntry zipEntry = new ZipEntry(file.getName());
                zos.putNextEntry(zipEntry);

                // Читаем файл и записываем в архив
                try (FileInputStream fis = new FileInputStream(file)) {
                    int length;
                    while ((length = fis.read(buffer)) > 0) {
                        zos.write(buffer, 0, length);
                    }
                }
                zos.closeEntry();
            }
            System.out.println("Архив создан: " + zipFileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Распаковка ZIP-архива

Для чтения архива используется ZipInputStream. Метод getNextEntry() последовательно возвращает все записи архива:

import java.io.*;
import java.util.zip.*;

public class ExtractZipExample {
    public static void main(String[] args) {
        String zipFileName = "archive.zip";
        String outputDir = "extracted_files";

        new File(outputDir).mkdir();

        try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFileName))) {
            ZipEntry entry;
            byte[] buffer = new byte[1024];

            while ((entry = zis.getNextEntry()) != null) {
                String fileName = entry.getName();
                File newFile = new File(outputDir + File.separator + fileName);

                // Создаем директории при необходимости
                new File(newFile.getParent()).mkdirs();

                try (FileOutputStream fos = new FileOutputStream(newFile)) {
                    int length;
                    while ((length = zis.read(buffer)) > 0) {
                        fos.write(buffer, 0, length);
                    }
                }
                zis.closeEntry();
                System.out.println("Распакован: " + fileName);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Работа с ZipFile для произвольного доступа

Если нужно получить доступ к конкретному файлу внутри архива без последовательного чтения, используйте ZipFile. Этот класс позволяет работать с архивом как с файловой системой:

import java.io.*;
import java.util.zip.*;
import java.util.Enumeration;

public class ZipFileExample {
    public static void main(String[] args) {
        try (ZipFile zipFile = new ZipFile("archive.zip")) {
            Enumeration<? extends ZipEntry> entries = zipFile.entries();

            while (entries.hasMoreElements()) {
                ZipEntry entry = entries.nextElement();
                System.out.println("Файл: " + entry.getName() +
                                   ", размер: " + entry.getSize() +
                                   ", сжатый размер: " + entry.getCompressedSize());

                // Получаем содержимое конкретного файла
                if (entry.getName().equals("file1.txt")) {
                    InputStream is = zipFile.getInputStream(entry);
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                    String line;
                    while ((line = reader.readLine()) != null) {
                        System.out.println("Содержимое file1.txt: " + line);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Добавление директорий в архив

При создании архива часто требуется сохранить структуру папок. Для этого в качестве имени записи указывается путь с разделителем "/":

// Создание записи для директории
ZipEntry dirEntry = new ZipEntry("subfolder/");
zos.putNextEntry(dirEntry);
zos.closeEntry();

// Добавление файла в поддиректорию
ZipEntry fileEntry = new ZipEntry                    

Рекомендаций