JDKでの圧縮と解凍

4726 ワード

1.ファイルの圧縮と解凍
基本的には簡単です.windowsプラットフォームでテストしました.コードをつけます.
 
package cn.tang.zip;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class MyZipUtil {

	public void unzip(File zipFile, File unzipFolder) throws IOException {
		if (!unzipFolder.exists()) {
			unzipFolder.mkdir();
		}
		ZipFile zip = new ZipFile(zipFile);
		unzip(zip, unzipFolder.getAbsolutePath());
		zip.close();
	}

	private void unzip(ZipFile zipFile, String parentDir) throws IOException {
		Enumeration<? extends ZipEntry> entries = zipFile.entries();
		byte[] buffer = new byte[128];
		while (entries.hasMoreElements()) {
			ZipEntry entry = entries.nextElement();
			String entryName = entry.getName();
			File f = new File(parentDir + File.separator + entryName);
			System.out.println(f.getAbsolutePath());
			if (entry.isDirectory()||entryName.endsWith("\\")||entryName.endsWith(File.separator)) {
				if (!f.exists()) {
					f.mkdir();
				}
			} else {
				if (!f.exists())
					f.createNewFile();
				OutputStream os = new BufferedOutputStream(new FileOutputStream(f));
				InputStream is = zipFile.getInputStream(entry);
				int count = -1;
				while ((count=is.read(buffer)) != -1) {
					os.write(buffer, 0, count);
				}
				os.close();
				is.close();
			}
		}
	}

	public void zip(File sourceFile, File zipFile) throws IOException {
		FileOutputStream fos = new FileOutputStream(zipFile);
		ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(fos));
		zip(sourceFile, out, "");
		out.close();
	}

	private void zip(File sourceFile, ZipOutputStream out, String parentDir) throws IOException {
		if (sourceFile == null || !sourceFile.exists())
			throw new FileNotFoundException();
		String currentPath = parentDir + sourceFile.getName();
		if (sourceFile.isDirectory()) {
			ZipEntry entry = new ZipEntry(currentPath + File.separator);
			out.putNextEntry(entry);
			for (File temp : sourceFile.listFiles()) {
				zip(temp, out, currentPath + File.separator);
			}
		} else {
			ZipEntry entry = new ZipEntry(currentPath);
			out.putNextEntry(entry);
			byte[] buffer = new byte[128];
			FileInputStream fis = new FileInputStream(sourceFile);
			BufferedInputStream bis = new BufferedInputStream(fis);
			int count = 0;
			while ((count = bis.read(buffer)) != -1) {
				out.write(buffer, 0, count);
			}
			bis.close();
		}
	}
}

ここでちょっと注意したいのは、ZipEntry.isDirectory()メソッドは、linuxプラットフォームではほとんど問題ありませんが、windowsプラットフォームでは使いにくいかもしれません.ソースを見ればわかる
 
 public boolean isDirectory()
    {
        return name.endsWith("/");
    }

 
 
 2.対流の圧縮と解凍
JDKでは、入力出力ストリームの解凍と圧縮を支援するいくつかのクラスが用意されています.
public class InflaterInputStream extends FilterInputStream
public class InflaterOutputStream extends FilterOutputStream
public class DeflaterInputStream extends FilterInputStream
public class DeflaterOutputStream extends FilterOutputStream

// 
public class DeflaterInputStream extends FilterInputStream
public class FilterInputStream extends InputStream

// 
 public DeflaterInputStream(InputStream inputstream)
    {
        this(inputstream, new Deflater());
        usesDefaultDeflater = true;
    }

protected FilterInputStream(InputStream inputstream)
    {
        in = inputstream;
    }
// , 

ここで注意したいのは、resetとmarkメソッドは使用できません.ソースコードを証明します.
  public synchronized void mark(int i)
    {
    }

    public synchronized void reset()
        throws IOException
    {
        throw new IOException("mark/reset not supported");
    }

最近hadoopのソースコードを见る时それがこの方法を実现したことを発见して、ちょうど兴味の学友は见ることができます
org.apache.hadoop.io.compress.zlib.ZlibCompressorというクラス