JavaでZipファイルを処理する
Javaのjava.util.zip配下には、圧縮・解凍など、Zipファイルを処理するクラスが定義されている。
これらを使って、Zipファイルの作成、解凍、圧縮ファイル一覧を取得するクラスを書いてみる。
import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.zip.CRC32; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; public class ZipIO { private static final int EOF=-1; private ZipFile zip; private byte[] buf; private String path=null; private ZipIO(){ buf=new byte[8092]; } /** * Zip内のファイル一覧を取得するメソッド * * @param f zipファイル * @return 圧縮ファイルのリスト */ public static List<String> getList(File f){ ZipIO z=new ZipIO(); return z.listZip(f); } /** * Zipファイルを解凍するメソッド * * @param dir 解凍先のディレクトリ * @param zip 解凍するZipファイル * @return 解凍の正否 */ public static boolean meltZip(File dir,File zip){ ZipIO z=new ZipIO(); z.path=dir.getAbsolutePath(); return z.meltZip(zip); } /** * Zipファイルを作成するメソッド * * @param zip 作成するZipファイル名 * @param basepath 圧縮ファイルの基準ディレクトリ * @param files 圧縮するファイル・ディレクトリの配列 * @return 圧縮の正否 */ public static boolean createZip(File zip,File basepath,File[] files){ ZipIO z=new ZipIO(); z.path=basepath.getAbsolutePath()+File.separator; return z.freezeeZip(zip,files); } private boolean freezeeZip(File zip,File[] entry){ try{ ZipOutputStream zos= new ZipOutputStream(new FileOutputStream(zip)); for(int i=0;i<entry.length;i++){ freezeFile(zos,entry[i]); } zos.close(); return true; }catch(IOException e){ e.printStackTrace(); return false; } } private void freezeFile(ZipOutputStream zos, File file){ if(file.isDirectory()){ File[] ff=file.listFiles(); for(int i=0;i<ff.length;i++){ freezeFile(zos,ff[i]); } }else{ System.out.println("ファイルを圧縮中...."); long num=addEntryFile(zos, file); long v=Math.round((double)num/(double)file.length()*100.0); System.out.println( "ファイルを圧縮中完了("+Long.toString(v)+"%)"); } } private long addEntryFile(ZipOutputStream zos, File file) { CRC32 crc=new CRC32(); try{ BufferedInputStream bis=new BufferedInputStream( new FileInputStream(file)); String tmp=file.getAbsolutePath(); tmp=tmp.replace(path, ""); ZipEntry entry=new ZipEntry(tmp); int size; byte[] bb=getFileBytes(file); crc.update(bb,0,(int)file.length()); entry.setSize(file.length()); entry.setCrc(crc.getValue()); zos.putNextEntry(entry); while((size=bis.read(buf,0,1024))!=EOF) { zos.write(buf,0,size); } bis.close(); zos.closeEntry(); return entry.getCompressedSize(); } catch (Exception e){ e.printStackTrace(); return -1; } } private static byte[] getFileBytes(File file) { FileInputStream fis = null; BufferedInputStream bis = null; try { int len = (int)file.length(); fis = new FileInputStream(file); bis = new BufferedInputStream(fis, len); byte buf[] = new byte[len]; bis.read(buf, 0, len); return buf; } catch (IOException e) { e.printStackTrace(); } finally { bis=null; } return null; } private boolean meltZip(File f){ try{ zip=new ZipFile(f.getAbsolutePath()); Enumeration<? extends ZipEntry> enu=zip.entries(); while(enu.hasMoreElements()){ extractFile((ZipEntry)enu.nextElement()); } return true; }catch(IOException e){ e.printStackTrace(); return false; } } private List<String> listZip(File f){ try{ zip=new ZipFile(f.getAbsolutePath()); Enumeration<? extends ZipEntry> enu=zip.entries(); List<String> ret=new ArrayList<String>(); while(enu.hasMoreElements()){ ret.addAll(listFile((ZipEntry)enu.nextElement())); } return ret; }catch(IOException e){ e.printStackTrace(); return null; } } private void extractFile(ZipEntry entry) throws IOException{ String name=entry.getName(); if(name.endsWith("/")){ name=path+File.separator+name; File dir=new File(name); if(!dir.exists()){ dir.mkdirs(); } }else{ if(name.contains("/")){ String[] dir=name.split("/"); String tmp=path+File.separator; for(int i=0;i<dir.length-1;i++){ File d=new File(tmp+dir[i]); if(!d.exists())d.mkdir(); tmp=tmp+dir[i]+File.separator; } name=path+File.separator+name; write(name,entry); }else if(name.contains("\\")){ String[] dir=name.split("\\\\"); String tmp=path+File.separator; for(int i=0;i<dir.length-1;i++){ File d=new File(tmp+dir[i]); if(!d.exists())d.mkdir(); tmp=tmp+dir[i]+File.separator; } name=path+File.separator+name; write(name,entry); }else{ name=path+File.separator+name; write(name,entry); } } } private void write(String name,ZipEntry entry) throws IOException{ FileOutputStream fs=new FileOutputStream(name); InputStream is=zip.getInputStream(entry); File ff=new File(name); System.out.println(ff.getAbsolutePath()); int n; while((n=is.read(buf))>0){ fs.write(buf,0,n); } is.close(); fs.close(); } private List<String> listFile(ZipEntry entry) throws IOException{ List<String> ret=new ArrayList<String>(); String name=entry.getName(); if(entry.isDirectory()){ ret.add("Dir :"+name); }else{ ret.add("File:"+name); } return ret; } }
■結果
ZipIOは、コンストラクタをprivateにしているので、インスタンスは生成できず、メソッドは、全てstaticメソッドとして提供しています。
getListがファイル一覧が取得、meltZipが解凍、createZipが圧縮を実行するメソッドです。