概要

JFileChooserで選択したzipファイルを展開、またはディレクトリをzip圧縮します。

サンプルコード

JButton button1 = new JButton("unzip");
button1.addActionListener(e -> {
  String str = field.getText();
  Path path = Paths.get(str);
  if (str.isEmpty() || Files.notExists(path)) {
    return;
  }
  String name = Objects.toString(path.getFileName());
  int lastDotPos = name.lastIndexOf('.');
  if (lastDotPos > 0) {
    name = name.substring(0, lastDotPos);
  }
  Path destDir = path.resolveSibling(name);
  try {
    if (Files.exists(destDir)) {
      String m = String.format(
          "<html>%s already exists.<br>Do you want to overwrite it?",
          destDir.toString());
      int rv = JOptionPane.showConfirmDialog(
          button1.getRootPane(), m, "Unzip", JOptionPane.YES_NO_OPTION);
      if (rv != JOptionPane.YES_OPTION) {
        return;
      }
    } else {
      if (LOGGER.isLoggable(Level.INFO)) {
        LOGGER.info("mkdir0: " + destDir.toString());
      }
      Files.createDirectories(destDir);
    }
    ZipUtil.unzip(path, destDir);
  } catch (IOException ex) {
    ex.printStackTrace();
  }
});
// ...
public static void unzip(Path zipFilePath, Path destDir) throws IOException {
  try (ZipFile zipFile = new ZipFile(zipFilePath.toString())) {
    Enumeration<? extends ZipEntry> e = zipFile.entries();
    while (e.hasMoreElements()) {
      ZipEntry zipEntry = e.nextElement();
      String name = zipEntry.getName();
      Path path = destDir.resolve(name);
      if (name.endsWith("/")) { // if (Files.isDirectory(path)) {
        log("mkdir1: " + path.toString());
        Files.createDirectories(path);
      } else {
        Path parent = path.getParent();
        if (Files.notExists(parent)) {
          log("mkdir2: " + parent.toString());
          Files.createDirectories(parent);
        }
        log("copy: " + path.toString());
        Files.copy(zipFile.getInputStream(zipEntry),
                   path, StandardCopyOption.REPLACE_EXISTING);
      }
    }
  }
}
View in GitHub: Java, Kotlin

解説

  • Zip
    • JFileChooser#setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)を設定して、ディレクトリのみ表示するJFileChooserzip圧縮する対象ディレクトリを選択
    • Files.walk(...)で対象ディレクトリ内を検索し、パスをZipEntryに変換してZipOutputStreamに追加、Files.copy(...)で書き出し
      public static void zip(Path srcDir, Path zip) throws IOException {
        try (Stream<Path> s = Files.walk(srcDir).filter(Files::isRegularFile)) {
          List<Path> files = s.collect(Collectors.toList());
          try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(zip))) {
            for (Path f: files) {
              String relativePath = srcDir.relativize(f).toString();
              ZipEntry ze = new ZipEntry(relativePath.replace('\\', '/'));
              zos.putNextEntry(ze);
              Files.copy(f, zos);
            }
          }
        }
      }
      
  • Unzip
    • JFileChooserで展開するzipファイルを選択
    • 対象ファイルをZipFileに変換して、ZipFile#entries()で圧縮されているファイルの一覧を取得
    • Files.copy(zipFile.getInputStream(zipEntry), path, StandardCopyOption.REPLACE_EXISTING)メソッドで展開

参考リンク

コメント