Статьи
YouTube-канал

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

29 января 2020

Тэги: Java Java 10 ввод-вывод

Содержание

  1. Обработка директории
  2. Обработка файла

Ранее мы рассматривали Создание zip-архивов, а теперь попробуем выполнить обратную операцию. Если у нас имеется zip-архив с файлами, то распаковать его мы можем следующим образом:

public static void main(String[] args) throws IOException {
    try (var file = new ZipFile("/home/devmark/Documents/test.zip")) {
        var entries = file.entries();
        var uncompressedDirectory = new File(file.getName()).getParent() + File.separator;
        while (entries.hasMoreElements()) {
            var entry = entries.nextElement();
            if (entry.isDirectory()) {
                processDirectory(uncompressedDirectory, entry);
            } else {
                processFile(file, uncompressedDirectory, entry);
            }
        }
    }
}

Мы создаём объект ZipFile из пакета java.util, в конструктор которому передаём полный путь до нашего архива. Все действия выполняем в конструкции try-with-resources, которая автоматически закроет ресурс, связанный с нашим архивом, в конце работы с ним.

Метод entries() предоставляет список содержащихся в архиве сущностей (файлов и папок). Затем мы можем обходить эти сущности при помощи цикла while и метода hasMoreElements(). Распакованный архив будем складывать в ту же директорию, где лежит исходный файл с архивом.

В цикле мы проверяем у каждой сущности признак isDirectory() и в зависимости от этого либо создаём подпапки в папке назначения, либо распаковываем содержащийся в архиве файл. Ниже приведены оба метода: processDirectory() и processFile().

Обработка директории

private static void processDirectory(String uncompressedDirectory, ZipEntry entry) {
    var newDirectory = uncompressedDirectory + entry.getName();
    System.out.println("Creating Directory: " + newDirectory);
    var directory = new File(newDirectory);
    if (!directory.exists()) {
        directory.mkdirs();
    }
}

Тут мы прибавляем к нашему базовому пути имя папки, содержащейся в архиве. Затем создаём объект File, асоциированный с этой новой папкой и проверяем её существование. Если её нет (что вполне ожидаемо), то создаем все папки с подпапками, содержащиеся в данном пути с помощью метода mkdirs().

Обработка файла

private static void processFile(ZipFile file, String uncompressedDirectory, ZipEntry entry) throws IOException {
    try (
            var is = file.getInputStream(entry);
            var bis = new BufferedInputStream(is)
    ) {
        var uncompressedFileName = uncompressedDirectory + entry.getName();
        try (
                var os = new FileOutputStream(uncompressedFileName);
                var bos = new BufferedOutputStream(os)
        ) {
            while (bis.available() > 0) {
                bos.write(bis.read());
            }
        }
    }
    System.out.println("Written: " + entry.getName());
}

В конструкции try-with-resources мы создаём поток InputStream, связанный с упакованным файлом внутри архива. Затем оборачиваем его буферизованным потоком BufferedInputStream, который минимизирует количество операций с файловой системой, что заметно ускоряет процесс распаковки.

Затем создаём аналогично поток FileOutputStream связанный с файлом, который мы собираемся записать. Оборачиваем его также в BufferedOutputStream для ускорения и в цикле пишем распакованный файл с помощью метода write().


Облако тэгов

Kotlin, Java, Java 16, Java 11, Java 10, Java 9, Java 8, Spring, Spring Boot, Spring Data, SQL, PostgreSQL, Oracle, Hibernate, Collections, Stream API, многопоточность, ввод-вывод, Apache, maven, gradle, JUnit, YouTube, новости, ООП, алгоритмы, головоломки, rest, GraphQL, Excel, XML, json, yaml

Последние статьи


Комментарии

Добавить комментарий

×

devmark.ru