首先,与此相关的类是java.util.zip.ZipOutputStream,其构造函数为ZipOutputStream(OutputStream out)。
下面以一个实例来说明如何用java完成对文件的压缩。
package ziptest;
import java.io.*;
import java.util.zip.*;
public class Zip{
static final int BUFFER = 2048;
static boolean flag = false;
public static void main(String[] args) throws IOException{
File file = new File("D:/TT");
boolean b1 = file.exists();
if(!b1)
throw new RuntimeException("The Dir is not exist!");
ZipSubdirectory(file);
//FileInputStream file1 = new FileInputStream(ZipSubdirectory(file)); //这两段话是为何...
//System.out.println(file1.toString());
}
public static File ZipSubdirectory(File myDir) throws IOException{
BufferedInputStream origin = null;
File zipFile = new File("D:/" + myDir.getName() + ".zip"); //此处为生成的zip文件的文件名
//File zipFile = new File("D:/" + "aaa" + ".zip"); //这样就将生成的zip文件改名了
System.out.println("Creat: D:/" + myDir.getName() + ".zip"); //调试用
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(fos,BUFFER));
//ZipOutputStream out = new ZipOutputStream(fos); //这么写也行,只是就不用缓冲文件了
File dirContents[] = myDir.listFiles();
File tempFile = null;
try{
for(int i = 0;i < dirContents.length;i++){
if(dirContents[i].isDirectory()){
tempFile = ZipSubdirectory(dirContents[i]); //这里就是个递归,因为是递归,所以子目录也被单独压缩了,当然,子目录的子目录也是
flag = true; //需要注意的是,这里进入递归之后,返回的tempFile是*.zip
}
else{
tempFile = dirContents[i];
flag = false;
}
System.out.println("Compress file:" + tempFile.getName()); //打印压缩内容信息,如果递归了,那么就压缩一个目录(也就是将.zip作为一个内容放入父目录)
FileInputStream fis = new FileInputStream(tempFile);
origin = new BufferedInputStream(fis,BUFFER);
ZipEntry entry = new ZipEntry(tempFile.getName()); //为被读取的文件创建压缩条目,否则只有目录,目录内无文件
byte[] data = new byte[BUFFER];
int count;
out.putNextEntry(entry); //在向ZIP输出流写入数据之前,必须首先使用out.putNextEntry(entry); 方法安置压缩条目对象
while((count = origin.read(data,0,BUFFER)) != -1){
out.write(data,0,count);
}
origin.close();
if(flag == true){ //这段语句删除tempFile目录失败,可能是没有关闭此文件的流
flag = tempFile.delete(); //如果是目录,会在D:/下又新建一个.zip,所以要删除
System.out.println("Delete file:"+tempFile.getName()+flag);
}
//origin.close(); //关闭缓冲流要是放在这,会导致上面这段语句执行失败
}
out.close();
}catch(Exception e){
System.out.println(e);
}
return zipFile;
}
}
这里对以上程序做个简要说明:
首先里面最重要的主体,ZipSubdirectory()方法是一个带返回值(返回类型为File,返回zipFile,具体作用看递归内容)的带参数(参数类型也为File)的方法,其中使用了递归来完成对子目录的压缩.
public BufferedOutputStream(OutputStream out,int size)是一个字节缓冲输出流,该方法实现创建给定大小输出缓冲区的缓冲字节输出流.
public ZipEntry(String name)name为指定的数据项名.
在向ZIP输出流写入数据之前,必须首先使用out.putNextEntry(entry) 方法安置压缩条目对象
解压缩代码
package test4;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
//import org.apache.tools.zip.*;
public class Test {
public static void main(String[] args) {
readFileAndWriteZip();
unZipFile();
}
public static void unZipFile() {
try{
//int BUFFER = 1024;
int BUFFER = 1024;
BufferedOutputStream dest = null;
FileInputStream fis = new FileInputStream("D:/2M.zip");
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
//ZipFile zis = new ZipFile(new BufferedInputStream(fis));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
System.out.println("Extracting: " + entry);
int count;
// byte data[] = new byte[1024];
byte data[] = new byte[1024];
FileOutputStream fos = new FileOutputStream("D:/Ta/"+entry.getName());
dest = new BufferedOutputStream(fos, BUFFER);
while ((count = zis.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
dest.flush();
dest.close();
}
zis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void readFileAndWriteZip() {
try {
} catch (Exception ex){
System.err.println(ex.toString());
}
}
}