JDK 中压缩和好压缩

JDK 中压缩和解压缩

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这个类