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"
java work.Zip "C:\\out.zip" "C:\\TEMP"
[実行結果]
C:\\out.zipが出来上がってるはず。
jav xvf out.zip
jav xvf out.zip
で解凍してみてねん。
でもって、(1)(2)のコメントを外して、(3)(4)(5)をコメントアウトすると
標準のJavaAPIが使われます。クラス名はいっしょなんだ。名前空間って
便利だねぇ♪