便利なコードパーツ集!

やまろうのプログラミングTips

Java

JavaでZIP圧縮。org.apache.tools.zipを使えば日本語ファイル名もOK

投稿日:

2005/03

ダウンロードするファイルを圧縮しなければならないっていう要件があって
ZIP圧縮するAPIを調べました。java.util.zipパッケージを使えば出来るんだけど、
圧縮するファイル名が日本語だと文字化けするみたいなんだ。しかも、ネット上の
java.util.zipを使ってるサンプルは、ほとんどがJavaWorldに乗ってたのをコピー
したやつで、動かして出来上がったZIPは解凍すると中身が空っぽだったりするんだ。
ってなわけで自分で作るっきゃないね♪

package work;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

//import java.util.zip.ZipEntry;                    (1)
//import java.util.zip.ZipOutputStream;             (2)
import org.apache.tools.zip.ZipEntry;             //(3)
import org.apache.tools.zip.ZipOutputStream;      //(4)

/**
 * ZIP圧縮する。
 * 
 * java work.Zip [ZIP出力ファイル名] [入力ファイル名(ディレクトリ)]…複数指定可
 * @author yamarou
 */
public class Zip {
  /** Zipエントリから削除するパスの長さ */
  private static int deleteLength;

  public static void main(String[] args) throws IOException {
    String[] targetFiles = new String[args.length - 1];
    System.arraycopy(args, 1, targetFiles, 0, targetFiles.length);
    createZip(args[0], targetFiles);
  }

  /**
   * targetFilesをZIP圧縮してzipFileに出力する。
   * @param zipFile ZIP出力ファイル名
   * @param targetFiles 入力ファイル名(ディレクトリ)配列
   * @throws IOException 入出力例外
   */
  public static void createZip(String zipFile, String[] targetFiles)
    throws IOException {

    ZipOutputStream out =
      new ZipOutputStream(new FileOutputStream(zipFile));
    out.setEncoding("MS932");                               //(5)
    for (int i = 0; i < targetFiles.length; i++) {
      File file = new File(targetFiles[i]);
      deleteLength = file.getPath().length() - file.getName().length();
      createZip(out, file);
    }
    out.close();
  }

  /**
   * targetFileをoutのZIPエントリへ出力する。
   * @param out ZIP出力先
   * @param targetFile 入力ファイル名(ディレクトリ)
   * @throws IOException 入出力例外
   */
  private static void createZip(ZipOutputStream out, File targetFile)
    throws IOException {

    if (targetFile.isDirectory()) {
      File[] files = targetFile.listFiles();
      for (int i = 0; i < files.length; i++) {
        createZip(out, files[i]);
      }
    } else {
      ZipEntry target = new ZipEntry(getEntryPath(targetFile));
      out.putNextEntry(target);
      byte buf[] = new byte[1024];
      int count;
      BufferedInputStream in =
        new BufferedInputStream(new FileInputStream(targetFile));
      while ((count = in.read(buf, 0, 1024)) != -1) {
        out.write(buf, 0, count);
      }
      in.close();
      out.closeEntry();
    }
  }

  /**
   * ZIPエントリパスを返す。
   * @param file ZIPエントリ対象ファイル
   * @return ZIPエントリのパス
   */
  private static String getEntryPath(File file) {
    return file.getPath().replaceAll("\\\\", "/").substring(deleteLength);
  }
}

実行にはant.jarが必要だからAntのサイトからダウンロードしてね。
[実行例]

set CLASSPATH=.;%CLASSPATH%;ant.jar
java work.Zip "C:\\out.zip" "C:\\TEMP"

[実行結果]

C:\\out.zipが出来上がってるはず。
jav xvf out.zip

で解凍してみてねん。

でもって、(1)(2)のコメントを外して、(3)(4)(5)をコメントアウトすると
標準のJavaAPIが使われます。クラス名はいっしょなんだ。名前空間って
便利だねぇ♪

スポンサーリンク

-Java

Copyright© やまろうのプログラミングTips , 2022 AllRights Reserved Powered by AFFINGER4.