понедельник, 3 октября 2011 г.

Упаковка и распаковка архива на Java

Java без посторонних библиотек поддерживает работу с несколькими видами архивов, в том числе и с самым популярным - Zip. Для этого используются классы из пакета java.util.zip. Давайте посмотрим, как с помощью этих инструментов можно упаковать и распаковать набор каталог с файлами и каталогами.
Упаковка:

  public static void pack(File directory, String to) throws IOException {
    URI base = directory.toURI();
    Deque<File> queue = new LinkedList<File>();
    queue.push(directory);
    OutputStream out = new FileOutputStream(new File(to));
    Closeable res = out;

    try {
      ZipOutputStream zout = new ZipOutputStream(out);
      res = zout;
      while (!queue.isEmpty()) {
        directory = queue.pop();
        for (File child : directory.listFiles()) {
          String name = base.relativize(child.toURI()).getPath();
          if (child.isDirectory()) {
            queue.push(child);
            name = name.endsWith("/") ? name : name + "/";
            zout.putNextEntry(new ZipEntry(name));
          } else {
            zout.putNextEntry(new ZipEntry(name));
            InputStream in = new FileInputStream(child);
            try {
              byte[] buffer = new byte[1024];
              while (true) {
                int readCount = in.read(buffer);
                if (readCount < 0) {
                  break;
                }
                zout.write(buffer, 0, readCount);
              }
            } finally {
              in.close();
            }
            zout.closeEntry();
          }
        }
      }
    } finally {
      res.close();
    }
  }



Этот метод интересен тем, что, в отличие от большинства методов для манипуляции с файлами, он нерекурсивный. Тут для обработки вложенных директорий используется очередь. Кстати, метод не мой, взят отсюда.
Обратный процесс также реализуем нерекурсивным методом.Проходим по всем entry в архиве, директории сразу создаём, файлы добавляем в очередь. Потом проходим по очереди и создаём файлы, копируя их из ZipInputStream в FileOutputStream:

  public static void unpack(String path, String dir_to) throws IOException {
    ZipFile zip = new
ZipFile(path);
    Enumeration entries = zip.entries();
    LinkedList<ZipEntry> zfiles = new LinkedList<ZipEntry>();
    while (entries.hasMoreElements()) {
      ZipEntry entry = (ZipEntry) entries.nextElement();
      if (entry.isDirectory()) {
        new File(dir_to+"/"+entry.getName()).mkdir();
      } else {
        zfiles.add(entry);
      }
    }
    for (ZipEntry entry : zfiles) {
      InputStream in = zip.getInputStream(entry);
      OutputStream out = new FileOutputStream(dir_to+"/"+entry.getName());
      byte[] buffer = new byte[1024];
      int len;
      while ((len = in.read(buffer)) >= 0)
        out.write(buffer, 0, len);
      in.close();
      out.close();
      }
    zip.close();
  }

1 комментарий: