zip压缩和解压工具类
注意事项:
1. 压缩空文件夹时,分隔符不能用File.seperate,应该用“/”,否则无法将空文件夹压缩为空文件夹,而是压缩为一个文件;
zipOut.putNextEntry(new ZipEntry(baseDir + "/"));
/**
*
* @Title: packFilesZip
* @Description: TODO(将多个文件打包成压缩文件)
* @return void 返回类型
* @param files 要打包的文件列表(不能是文件夹,不能为null)
* @param zipUrl 打包存放位置(最好压缩之前调用生成文件的方法,防止抛异常)
* @throws Exception
*/
/**
*
* @Title: fileToZip
* @Description: TODO(压缩指定的文件夹或者文件)
* @return void 返回类型
* @param zipUrl 压缩文件的url,(在压缩之前调用创建文件的方法)
* @param file 要压缩的文件或者文件夹(不能为null)
* @param baseDir 压缩文件的根目录
* @throws IOException
*/
/**
*
* @Title: zipToFile
* @Description: TODO(解压zip文件到文件夹)注意:无法解压经过360zip压缩过的文件
* @return void 返回类型
* @param zipPath 压缩文件的路径
* @param prefix 目标文件夹的路径例如:c:/a/,结尾有分隔符
* @throws IOException
*/
完整代码如下:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.junit.Test;
public class ZipUtils {
/**
*
* @Title: packFilesZip
* @Description: TODO(将多个文件打包成压缩文件)
* @return void 返回类型
* @param files 要打包的文件列表(不能是文件夹,不能为null)
* @param zipUrl 打包存放位置(最好压缩之前调用生成文件的方法,防止抛异常)
* @throws Exception
*/
public static void packFilesZip(File[] files, String zipUrl) throws Exception {
ZipOutputStream zipOut = null;
try {
// 构建压缩包文件输出流,根据路径生成压缩包文件
zipOut = new ZipOutputStream(new FileOutputStream(zipUrl));
// 遍历要放入压缩包内的文件
for (int i = 0; i < files.length; i++) {
if (files[i] == null || !files[i].exists()) {
System.err.print("文件不存在:error" + i);
continue;
}
InputStream input = null;
BufferedInputStream bufferedInput = null;
try {
// 用于读取文件
input = new FileInputStream(files[i]);
bufferedInput = new BufferedInputStream(input);
// 在压缩包内构建一个与本地文件一样命名的实体文件
ZipEntry zipEntry = new ZipEntry(files[i].getName());
zipEntry.setSize(files[i].length());
zipOut.putNextEntry(zipEntry);
// 边读文件,边向压缩包内的同名实体文件复制(写)数据
int len = -1;
byte[] bytes = new byte[1024];
while ((len = bufferedInput.read(bytes)) != -1) {
zipOut.write(bytes, 0, len);
}
zipOut.closeEntry();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(bufferedInput != null) {
bufferedInput.close();
}
if(input != null) {
input.close();
}
}
}
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
if(zipOut != null) {
zipOut.close();
}
}
}
/**
*
* @Title: fileToZip
* @Description: TODO(压缩指定的文件夹或者文件)
* @return void 返回类型
* @param zipUrl 压缩文件的url,(在压缩之前调用创建文件的方法)
* @param file 要压缩的文件或者文件夹(不能为null)
* @param baseDir 压缩文件的根目录
* @throws IOException
*/
public static void fileToZip(String zipUrl, File file, String baseDir) throws IOException {
if(baseDir == null) {
baseDir = file.getName();
}
// 压缩输出流
ZipOutputStream zipOut = null;
BufferedOutputStream bufferedOut = null;
try {
File zipFile = new File(zipUrl);
zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
bufferedOut = new BufferedOutputStream(zipOut);
//开始压缩
zipProcess(zipOut, bufferedOut, file, baseDir);
zipOut.closeEntry();
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
if (bufferedOut != null) {
bufferedOut.close();
}
if (zipOut != null) {
zipOut.close();
}
}
}
/**
*
* @Title: zipProcess
* @Description: TODO(压缩指定的文件夹或者文件)
* @return void 返回类型
* @param zipOut zip输出流
* @param bufferedOut 高效输出流
* @param file 要压缩的文件或者文件夹
* @param baseDir 压缩文件的根目录
* @throws IOException
*/
private static void zipProcess(ZipOutputStream zipOut, BufferedOutputStream bufferedOut, File file, String baseDir)
throws IOException {
if (file.isDirectory()) { // 当前文件是文件夹
File[] childFiles = file.listFiles();
// 当前文件夹没有子元素
if (childFiles.length == 0) {
// 在压缩文件中创建文件夹(定位)
zipOut.putNextEntry(new ZipEntry(baseDir + "/"));
zipOut.closeEntry();
} else {
for (int i = 0; i < childFiles.length; i++) {
String currentBaseDir = baseDir + File.separator + childFiles[i].getName();
// 递归遍历子文件或文件夹
zipProcess(zipOut, bufferedOut, childFiles[i], currentBaseDir);
}
}
} else { // 当前文件是文件
// 创建文件
zipOut.putNextEntry(new ZipEntry(baseDir));
FileInputStream input = null;
BufferedInputStream bufferIn = null;
try {
input = new FileInputStream(file);
bufferIn = new BufferedInputStream(input);
int b;
while ((b = bufferIn.read()) != -1) {
bufferedOut.write(b); // 将字节流写入当前zip目录
}
//关闭之前最好flush,保证数据全部输出
bufferedOut.flush();
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
//关闭输入流
if(bufferIn != null) {
bufferIn.close();
}
if(input != null) {
input.close();
}
}
}
}
/**
*
* @Title: zipToFile
* @Description: TODO(解压zip文件到文件夹)注意:无法解压经过360zip压缩过的文件
* @return void 返回类型
* @param zipPath 压缩文件的路径
* @param prefix 目标文件夹的路径例如:c:/a/,结尾有分隔符
* @throws IOException
*/
public static void zipToFile(String zipPath, String prefix) throws IOException {
if (zipPath == null || zipPath.equals("")) {
throw new NullPointerException("File is not exist!");
}
File zipFile = new File(zipPath);
if(zipFile.exists() && zipFile.isFile()) {
InputStream inputStream = null;
ZipInputStream zin = null;
try {
inputStream = new FileInputStream(zipFile);
zin = new ZipInputStream(inputStream);
ZipEntry ze;
while ((ze = zin.getNextEntry()) != null) {
if (ze.isDirectory()) {
File file = new File(prefix + ze.getName());
if (!file.exists()) {
file.mkdirs();
}
continue;
}
File file = new File(prefix + ze.getName());
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
OutputStream outputStream = null;
BufferedOutputStream bufferedOut = null;
try {
outputStream = new FileOutputStream(file);
bufferedOut = new BufferedOutputStream(outputStream);
int len = -1;
byte[] bytes = new byte[1024];
while((len = zin.read(bytes)) != -1) {
bufferedOut.write(bytes, 0, len);
}
//关闭之前最好flush,保证数据全部输出
bufferedOut.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(bufferedOut != null) {
bufferedOut.close();
}
if(outputStream != null) {
outputStream.close();
}
}
}
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
zin.close();
inputStream.close();
}
}
}
@Test
public void testPackFilesZip() throws Exception {
File file = new File("C:\\Users\\Administrator\\Desktop\\c_code");
File[] files = file.listFiles();
packFilesZip(files, "C:\\Users\\Administrator\\Desktop\\c_code.zip");
}
@Test
public void testFileToZip() throws Exception {
File file = new File("C:\\Users\\Administrator\\Desktop\\c_code");
fileToZip("C:\\Users\\Administrator\\Desktop\\c_code.zip", file, file.getName());
}
@Test
public void testZipToFile() throws Exception {
zipToFile("C:\\Users\\Administrator\\Desktop\\c_code.zip", "C:\\Users\\Administrator\\Desktop\\c_code1\\");
}
}