Home » Пример распаковки файлов в Java
Пример распаковки файлов в Java

Пример распаковки файлов в Java

Сегодня разберёмся с одной из тех задач, которые вроде бы просты, но на практике часто вызывают вопросы: как распаковать архив (zip, tar, rar и т.д.) средствами Java? Почему это важно? Потому что автоматизация развёртывания, обновления, резервного копирования и прочих серверных рутин — это не только про bash-скрипты и ansible, но и про интеграцию с приложениями, где Java — частый гость. Если вы когда-нибудь писали свой deployer, автосборщик, или просто хотели автоматизировать развертывание WAR-файлов, то наверняка сталкивались с задачей распаковки архивов. В этой статье — не только базовые примеры, но и реальные кейсы, подводные камни, сравнения с альтернативами и советы, которые сэкономят вам кучу времени.

Как это работает? — Архивы и Java: что под капотом

В Java есть встроенная поддержка работы с архивами, но она ограничена zip-форматом (и, как ни странно, jar — это тоже zip). Для других форматов (tar, rar, 7z) придётся подключать сторонние библиотеки. В стандартной библиотеке (java.util.zip) есть классы ZipInputStream, ZipFile, ZipEntry — с их помощью можно читать, создавать и распаковывать zip-архивы. Для tar, gzip, bzip2 и прочих — используем Apache Commons Compress или junrar для rar.

  • Zip — поддерживается из коробки.
  • Tar, Gzip, Bzip2 — Apache Commons Compress (официальный сайт).
  • Rar — junrar (github).
  • 7z — SevenZipJBinding (github), но тут уже сложнее.

Всё это позволяет не только распаковывать архивы, но и интегрировать этот процесс в ваши приложения, автоматизировать деплой, обновления, миграции данных и прочие серверные задачи.

Как быстро и просто всё настроить?

Рассмотрим два сценария:

  • 1. Нужно просто распаковать zip-архив средствами Java (например, для автодеплоя на сервере).
  • 2. Требуется поддержка других форматов (tar, rar, 7z).

1. Распаковка zip-архива стандартными средствами Java

Всё, что нужно — JDK 8+ (лучше 11+), никаких дополнительных зависимостей. Вот пример кода:


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

public class Unzipper {
public static void unzip(String zipFilePath, String destDir) throws IOException {
File dir = new File(destDir);
if (!dir.exists()) dir.mkdirs();
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath))) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
File newFile = new File(destDir, entry.getName());
if (entry.isDirectory()) {
newFile.mkdirs();
} else {
new File(newFile.getParent()).mkdirs();
try (FileOutputStream fos = new FileOutputStream(newFile)) {
byte[] buffer = new byte[4096];
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
}
}
zis.closeEntry();
}
}
}
}

Вызов:


Unzipper.unzip("/path/to/archive.zip", "/path/to/destination/");

Плюсы: просто, работает везде, не требует зависимостей.
Минусы: только zip, нет поддержки rar/tar/7z, нет прогресса, нет защиты от path traversal (см. ниже!).

2. Распаковка других форматов — Apache Commons Compress

Добавьте зависимость в ваш pom.xml (если используете Maven):


<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.26.1</version>
</dependency>

Пример для tar.gz:


import org.apache.commons.compress.archivers.tar.*;
import org.apache.commons.compress.compressors.gzip.*;

public static void untarGz(String tarGzPath, String destDir) throws IOException {
try (TarArchiveInputStream tis = new TarArchiveInputStream(
new GzipCompressorInputStream(new FileInputStream(tarGzPath)))) {
TarArchiveEntry entry;
while ((entry = tis.getNextTarEntry()) != null) {
File newFile = new File(destDir, entry.getName());
if (entry.isDirectory()) {
newFile.mkdirs();
} else {
new File(newFile.getParent()).mkdirs();
try (FileOutputStream fos = new FileOutputStream(newFile)) {
byte[] buffer = new byte[4096];
int len;
while ((len = tis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
}
}
}
}
}

Для rar — используйте junrar, для 7z — SevenZipJBinding (но там придётся повозиться с нативными библиотеками).

Примеры, схемы, практические советы

Вот несколько реальных кейсов, с которыми сталкивался лично или видел на stackoverflow/habr:

  • Кейс 1: Автоматизация деплоя на сервере
    Нужно развернуть свежий билд приложения (zip-архив) на сервере после CI/CD. Решение — скрипт на Java, который скачивает архив, распаковывает в нужную директорию, перезапускает сервис. Всё просто, если архив zip. Если tar.gz — используем Apache Commons Compress.
  • Кейс 2: Распаковка пользовательских архивов
    Пользователь загружает архив с файлами (например, для импорта данных). Тут важно: архив может быть с сюрпризами (path traversal, вложенные архивы, нестандартные имена файлов). Рекомендация — всегда проверяйте, что путь распаковываемого файла не выходит за пределы целевой директории:

    File destFile = new File(destDir, entry.getName());
    String destPath = destFile.getCanonicalPath();
    if (!destPath.startsWith(new File(destDir).getCanonicalPath() + File.separator)) {
    throw new IOException("Entry is outside of the target dir: " + entry.getName());
    }

    Это защитит от атак типа ../../etc/passwd.
  • Кейс 3: Распаковка больших архивов
    Если архив огромный (гигабайты), лучше использовать стриминговую распаковку (ZipInputStream, TarArchiveInputStream), чтобы не держать всё в памяти. Для прогресса — можно считать количество обработанных байт и выводить в лог.

Таблица сравнения: стандартные средства vs сторонние библиотеки

Решение Форматы Зависимости Платформенность Особенности
java.util.zip zip, jar нет любая Встроено в JDK, просто, но только zip
Apache Commons Compress zip, tar, gzip, bzip2, ar, cpio, xz, 7z (ограниченно) да любая Гибко, поддержка многих форматов, активно развивается
junrar rar да любая Только rar, не всегда поддерживает rar5
SevenZipJBinding 7z, zip, rar, tar, gzip, bzip2 да (и нативные библиотеки) ограничено (нужен native) Мощно, но сложнее в настройке, нужен native

Похожие решения, программы и утилиты

  • unzip, tar, 7z — классика для Linux. Можно вызывать из Java через ProcessBuilder, если не хочется возиться с библиотеками.
  • Ant — в Ant есть задачи <unzip>, <untar> и т.д. Можно использовать через Ant API.
  • Spring Boot DevTools — умеет автоматически распаковывать jar/war при hot reload, но это уже специфично.

Если задача — просто распаковать архив на сервере, проще всего использовать стандартные утилиты ОС. Но если нужно интегрировать распаковку в Java-приложение (например, для автоматизации деплоя, миграций, обработки пользовательских архивов) — лучше использовать Java-библиотеки.

Статистика, сравнение с другими решениями

  • По данным Maven Central, Apache Commons Compress — одна из самых популярных библиотек для работы с архивами в Java (более 100 млн загрузок).
  • Стандартный java.util.zip используется в большинстве Java-проектов, но только для zip/jar.
  • junrar и SevenZipJBinding — нишевые решения, но незаменимы, если нужно работать с rar/7z.
  • В крупных проектах (например, Jenkins, Nexus, Artifactory) для работы с архивами часто используют именно Apache Commons Compress.

Интересные факты и нестандартные способы использования

  • Можно распаковывать архивы “на лету” из потока (например, скачивать архив по HTTP и сразу распаковывать, не сохраняя на диск).
  • Некоторые архивы (особенно rar, 7z) могут содержать вложенные архивы — для их обработки потребуется рекурсивная распаковка.
  • В Java можно создавать самораспаковывающиеся jar-файлы (fat jar), которые при запуске сами себя распаковывают и запускают нужный класс.
  • Для защиты от path traversal атак всегда проверяйте canonical path (см. выше).
  • Можно использовать распаковку архивов для автоматизации обновления конфигураций, миграций, резервного копирования (например, nightly-архивы с логами, которые потом автоматически распаковываются и анализируются).

Какие новые возможности открываются и чем это поможет в автоматизации и скриптах?

  • Интеграция распаковки архивов в ваши Java-приложения позволяет автоматизировать деплой, обновления, миграции данных без внешних скриптов.
  • Можно реализовать “горячее” обновление приложения: скачали новый билд, распаковали, перезапустили сервис — всё из одного Java-процесса.
  • Обработка пользовательских архивов (например, импорт данных, загрузка плагинов) становится безопаснее и проще.
  • Можно строить сложные пайплайны обработки данных: скачали архив → распаковали → обработали файлы → удалили временные данные.
  • Возможность работы с архивами “на лету” (streaming) экономит место на диске и ускоряет обработку больших данных.

Вывод — заключение и рекомендации

Распаковка архивов в Java — задача, с которой сталкивается каждый, кто автоматизирует серверные процессы, деплой, обновления или просто интегрирует работу с файлами в свои приложения. Если вам нужен быстрый и надёжный способ распаковать zip-архив — используйте стандартный java.util.zip. Для других форматов (tar, gzip, bzip2, rar, 7z) — подключайте Apache Commons Compress или специализированные библиотеки (junrar, SevenZipJBinding). Не забывайте про безопасность: всегда проверяйте пути файлов, чтобы избежать path traversal атак.

Если вы ищете хостинг для своих Java-приложений — обратите внимание на VPS или выделенные серверы — это даст вам полный контроль над окружением и возможностью автоматизировать любые задачи, включая распаковку архивов средствами Java.

Встраивайте распаковку архивов в свои пайплайны, автоматизируйте деплой, делайте резервные копии, обрабатывайте пользовательские данные — всё это реально и удобно с помощью Java. А если хочется ещё больше автоматизации — комбинируйте Java с bash-скриптами, ansible, docker и CI/CD. Главное — не бойтесь экспериментировать и автоматизировать рутину!

Официальные ресурсы для самостоятельного изучения:

Если остались вопросы — смело спрашивайте в комментариях, делитесь своими кейсами и лайфхаками. Happy hacking!


В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.

Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.

Leave a reply

Your email address will not be published. Required fields are marked