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が使われます。クラス名はいっしょなんだ。名前空間って
便利だねぇ♪