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