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.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import com.hyb.constant.Constant;
/**
* <p>
* 程序实现了ZIP压缩[compression]
* <p>
* 大致功能包括用了多态,递归等JAVA核心技术,可以对单个文件和任意级联文件夹进行压缩和解压。 需在代码中自定义源输入路径和目标输出路径。
* <p>
* 在本段代码中,实现的是压缩部分
*/
public class ZipUtil {
/**
* @param zipFileName
* 生成后得压缩文件目录
* @param inputFile
* 要压缩的目录
* @throws Exception
*/
public static void zip(String zipFileName, File inputFile) throws Exception {
Constant.LOGGER.info("压缩中...");
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
BufferedOutputStream bo = new BufferedOutputStream(out);
zip(out, inputFile, inputFile.getName(), bo);
bo.close();
out.close(); // 输出流关闭
Constant.LOGGER.info("压缩完成");
}
public static void zip(ZipOutputStream out, File f, String base,
BufferedOutputStream bo) throws Exception { // 方法重载
if (f.isDirectory()) {
File[] fl = f.listFiles();
if (fl.length == 0) {
out.putNextEntry(new ZipEntry(base + "/")); // 创建zip压缩进入点base
Constant.LOGGER.info(base + "/");
}
for (int i = 0; i < fl.length; i++) {
zip(out, fl[i], base + "/" + fl[i].getName(), bo); // 递归遍历子文件夹
}
} else {
out.putNextEntry(new ZipEntry(base)); // 创建zip压缩进入点base
Constant.LOGGER.info(base);
FileInputStream in = new FileInputStream(f);
BufferedInputStream bi = new BufferedInputStream(in);
int b;
while ((b = bi.read()) != -1) {
bo.write(b); // 将字节流写入当前zip目录
}
bi.close();
in.close(); // 输入流关闭
}
}
public static void zip(String srcPath, String zipPath, String zipFileName)
throws Exception {
CheckedOutputStream cos = null;
ZipOutputStream zos = null;
try {
File srcFile = new File(srcPath);
// 判断压缩文件保存的路径是否为源文件路径的子文件夹,如果是,则抛出异常(防止无限递归压缩的发生)
if (srcFile.isDirectory() && zipPath.indexOf(srcPath) != -1) {
throw new Exception("压缩文件保存的路径是否为源文件路径的子文件夹");
}
// 判断压缩文件保存的路径是否存在,如果不存在,则创建目录
File zipDir = new File(zipPath);
if (!zipDir.exists() || !zipDir.isDirectory()) {
zipDir.mkdirs();
}
// 创建压缩文件保存的文件对象
String zipFilePath = zipPath + File.separator + zipFileName;
File zipFile = new File(zipFilePath);
cos = new CheckedOutputStream(new FileOutputStream(zipFile),
new CRC32());
zos = new ZipOutputStream(cos);
// 如果只是压缩一个文件,则需要截取该文件的父目录
String srcRootDir = srcPath;
if (srcFile.isFile()) {
int index = srcPath.lastIndexOf(File.separator);
if (index != -1) {
srcRootDir = srcPath.substring(0, index);
}
}
// 调用递归压缩方法进行目录或文件压缩
zip(srcRootDir, srcFile, zos);
zos.flush();
} catch (Exception e) {
throw e;
} finally {
try {
if (zos != null) {
zos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static void zip(String srcRootDir, File file, ZipOutputStream zos) throws Exception {
if (file == null) {
return;
}
// 如果是文件,则直接压缩该文件
if (file.isFile()) {
int count, bufferLen = 1024;
byte data[] = new byte[bufferLen];
// 获取文件相对于压缩文件夹根目录的子路径
// String subPath = file.getAbsolutePath();
// int index = subPath.indexOf(srcRootDir);
// if (index != -1) {
// subPath = subPath.substring(srcRootDir.length() + File.separator.length());
// }
ZipEntry entry = new ZipEntry(file.getName());
zos.putNextEntry(entry);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
while ((count = bis.read(data, 0, bufferLen)) != -1) {
zos.write(data, 0, count);
}
bis.close();
zos.closeEntry();
}
// 如果是目录,则压缩整个目录
else {
// 压缩目录中的文件或子目录
File[] childFileList = file.listFiles();
for (int n = 0; n < childFileList.length; n++) {
childFileList[n].getAbsolutePath().indexOf(file.getAbsolutePath());
zip(srcRootDir, childFileList[n], zos);
}
}
}
public static void unzip(String zipPath, String targetPath) {
long startTime=System.currentTimeMillis();
try {
ZipInputStream zin=new ZipInputStream(new FileInputStream(zipPath));//输入源zip路径
BufferedInputStream bin=new BufferedInputStream(zin);
File Fout=null;
ZipEntry entry;
try {
while((entry = zin.getNextEntry())!=null && !entry.isDirectory()){
Fout=new File(targetPath,entry.getName());
if(!Fout.exists()){
(new File(Fout.getParent())).mkdirs();
}
FileOutputStream out=new FileOutputStream(Fout);
BufferedOutputStream Bout=new BufferedOutputStream(out);
int b;
while((b=bin.read())!=-1){
Bout.write(b);
}
Bout.close();
out.close();
Constant.LOGGER.info(Fout+"解压成功");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bin != null) {
bin.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (zin != null) {
zin.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
long endTime=System.currentTimeMillis();
Constant.LOGGER.info("耗费时间: "+(endTime-startTime)+" ms");
}
/**
* 测试
*
* @param args
*/
public static void main(String[] args) {
try {
// ZipUtil.zip("G:\\a.zip", new File("G:\\a"));
unzip("G:\\a.zip", "G:\\a");
} catch (Exception e) {
e.printStackTrace();
}
}
}