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

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

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

Начать курс

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

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

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

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

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

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

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

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

public class CreateZip {
    public static void main(String[] args) throws IOException {
        String[] sourceFiles = {"file1.txt", "file2.txt", "image.png"};
        String zipName = "archive.zip";

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

            for (String filePath : sourceFiles) {
                File file = new File(filePath);
                FileInputStream fis = new FileInputStream(file);

                // Создаём запись в архиве
                ZipEntry zipEntry = new ZipEntry(file.getName());
                zos.putNextEntry(zipEntry);

                // Записываем содержимое файла
                int length;
                while ((length = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, length);
                }
                zos.closeEntry();
                fis.close();
                System.out.println("Добавлен: " + file.getName());
            }
        }
        System.out.println("Архив создан: " + zipName);
    }
}

Важные нюансы при создании архива:

  • Всегда вызывайте putNextEntry() перед записью данных и closeEntry() после
  • Для добавления пустой директории используйте ZipEntry(name + "/") — имя должно заканчиваться на "/"
  • Используйте try-with-resources для автоматического закрытия потоков

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

Для извлечения файлов из архива применяется ZipInputStream. Чтение происходит последовательно — запись за записью.

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

public class ExtractZip {
    public static void main(String[] args) throws IOException {
        String zipFile = "archive.zip";
        String outputDir = "extracted";

        File dir = new File(outputDir);
        if (!dir.exists()) dir.mkdirs();

        try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
            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();

                // Записываем файл
                FileOutputStream fos = new FileOutputStream(newFile);
                int length;
                while ((length = zis.read(buffer)) > 0) {
                    fos.write(buffer, 0, length);
                }
                fos.close();
                zis.closeEntry();

                System.out.println("Извлечён: " + fileName);
            }
        }
        System.out.println("Распаковка завершена в папку: " + outputDir);
    }
}

Прямой доступ к записям архива (ZipFile)

Класс ZipFile предоставляет более удобный способ работы с архивами — вы можете получать записи по имени, перебирать их, не распаковывая файлы полностью.

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

public class ReadZipEntries {
    public static void main(String[] args) throws IOException {
        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());
                System.out.println("  Размер: " + entry.getSize() + " байт");
                System.out.println("  Сжатый размер: " + entry.getCompressedSize() + " байт");
                System.out.println("  CRC32: " + Long.toHexString(entry.getCrc()));
                System                    

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