转载原文:
写了一个系列,写的很好,强烈推荐去看!
Java压缩技术(二) ZIP压缩——Java原生实现
Java压缩技术(三) ZIP解压缩——Java原生实现
Zip压缩/解压缩工具类
缺点:
- 压缩包内中文文件名会乱码;
- 压缩/解压缩不支持设置密码;
- 修改缓存系数线程不安全(不让改缓存系数就安全了);
代码:
package repalce.your.package;
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.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
* Zip压缩工具类(修改缓存系数线程不安全)
*/
public class ZipUtil {
/** 文件拓展名 */
public static final String EXT = ".zip";
/** 缓存大小 */
public static final int BUFFER_SIZE = 1024;
/** 缓存系数 */
private static int bufferCoefficient = 8;
/**
* 获取缓存系数
* @return 缓存系数
*/
public static int setBufferCoefficient(){
return bufferCoefficient;
}
/**
* 设置缓存系数
* @param bufferCoefficient 缓存系数(大于等于1)
*/
public static void setBufferCoefficient(int bufferCoefficient) {
if(bufferCoefficient < 1) {
ZipUtil.bufferCoefficient = 1;
}else{
ZipUtil.bufferCoefficient = bufferCoefficient;
}
}
// --压缩--------------------------------------------------------------------
/**
* 压缩
* @param srcPath 待压缩文件路径
* @throws IOException IO异常
*/
public static void compress(String srcPath) throws IOException {
compress(new File(srcPath));
}
/**
* 压缩
* @param srcFile 待压缩文件
* @throws IOException IO异常
*/
public static void compress(File srcFile) throws IOException {
// 检查待压缩文件是否为目录
if(srcFile.isDirectory()) {
compress(srcFile, srcFile.getParent() + File.separator + srcFile.getName() + EXT);
}else{
// 拓展名起始下标
int extStartIndex = srcFile.getName().lastIndexOf(".");
// 获取待压缩文件名称
String srcFileName = srcFile.getName().substring(0, extStartIndex == -1 ? srcFile.getName().length() : extStartIndex);
// 压缩
compress(srcFile, srcFile.getParent() + File.separator + srcFileName + EXT);
}
}
/**
* 压缩
* @param srcPath 待压缩文件路径
* @param destPath 压缩文件路径
* @throws IOException IO异常
*/
public static void compress(String srcPath, String destPath) throws IOException {
compress(new File(srcPath), destPath);
}
/**
* 压缩
* @param srcFile 待压缩文件
* @param destPath 压缩文件路径
* @throws IOException IO异常
*/
public static void compress(File srcFile, String destPath) throws IOException {
compress(srcFile, new File(destPath));
}
/**
* 压缩
* @param srcPath 待压缩文件路径
* @param destFile 压缩文件
* @throws IOException IO异常
*/
public static void compress(String srcPath, File destFile) throws IOException {
compress(new File(srcPath), destFile);
}
/**
* 压缩
* @param srcFile 待压缩文件
* @param destFile 压缩文件
* @throws IOException IO异常
*/
public static void compress(File srcFile, File destFile) throws IOException {
CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(destFile), new CRC32());
ZipOutputStream zos = new ZipOutputStream(cos);
compress(srcFile, zos, "");
zos.flush();
zos.close();
}
/**
* 压缩
* @param srcFile 源路径
* @param zos Zip输出流
* @param path 压缩包内相对路径
* @throws IOException IO异常
*/
private static void compress(File srcFile, ZipOutputStream zos, String path) throws IOException {
// 检查待压缩文件是否为目录
if (srcFile.isDirectory()) {
compressDir(srcFile, zos, path);
} else {
compressFile(srcFile, zos, path);
}
}
/**
* 压缩目录
* @param dir 目录文件
* @param zos Zip输出流
* @param path 压缩包内相对路径
* @throws IOException IO异常
*/
private static void compressDir(File dir, ZipOutputStream zos, String path) throws IOException {
// 目录下所有文件
File[] files = dir.listFiles();
// 构建空目录
if (files.length < 1) {
ZipEntry entry = new ZipEntry(path + dir.getName() + File.separator);
zos.putNextEntry(entry);
zos.closeEntry();
}
// 递归压缩
for (File file : files) {
compress(file, zos, path + dir.getName() + File.separator);
}
}
/**
* 压缩文件
* @param file 待压缩文件
* @param zos Zip输出流
* @param path 压缩文件中的当前路径
* @throws IOException IO异常
*/
private static void compressFile(File file, ZipOutputStream zos, String path) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
ZipEntry entry = new ZipEntry(path + file.getName());
zos.putNextEntry(entry);
int count;
byte data[] = new byte[BUFFER_SIZE * bufferCoefficient];
while ((count = bis.read(data, 0, BUFFER_SIZE * bufferCoefficient)) != -1) {
zos.write(data, 0, count);
}
bis.close();
zos.closeEntry();
}
// --解压--------------------------------------------------------------------
/**
* 解压缩
*
* @param srcPath 待解压文件路径
* @throws IOException IO异常
*/
public static void decompress(String srcPath) throws IOException {
decompress(new File(srcPath));
}
/**
* 解压缩
*
* @param srcFile 待解压文件
* @throws IOException IO异常
*/
public static void decompress(File srcFile) throws IOException {
decompress(srcFile, srcFile.getParent());
}
/**
* 解压缩
*
* @param srcPath 待解压文件路径
* @param destFile 释放目录
* @throws IOException IO异常
*/
public static void decompress(String srcPath, File destFile) throws IOException {
decompress(new File(srcPath), destFile);
}
/**
* 解压缩
*
* @param srcFile 待解压文件
* @param destPath 释放目录路径
* @throws IOException IO异常
*/
public static void decompress(File srcFile, String destPath) throws IOException {
decompress(srcFile, new File(destPath));
}
/**
* 解压缩
*
* @param srcPath 待解压文件路径
* @param destPath 释放目录路径
* @throws IOException
*/
public static void decompress(String srcPath, String destPath) throws IOException {
decompress(new File(srcPath), new File(destPath));
}
/**
* 解压缩
*
* @param srcFile 待解压文件
* @param destFile 释放目录
* @throws IOException IO异常
*/
public static void decompress(File srcFile, File destFile) throws IOException {
CheckedInputStream cis = new CheckedInputStream(new FileInputStream(srcFile), new CRC32());
ZipInputStream zis = new ZipInputStream(cis);
decompress(destFile, zis);
zis.close();
}
/**
* 解压缩
*
* @param destFile 释放目录
* @param zis Zip输入流
* @throws IOException IO异常
*/
private static void decompress(File destFile, ZipInputStream zis) throws IOException {
ZipEntry entry = null;
while ((entry = zis.getNextEntry()) != null) {
// 文件
File dirFile = new File(destFile.getPath() + File.separator + entry.getName());
// 文件检查
fileProber(dirFile);
// 检查是否为文件夹
if (entry.isDirectory()) {
dirFile.mkdirs(); // 创建文件夹
} else {
decompressFile(dirFile, zis); // 解压文件
}
zis.closeEntry();
}
}
/**
* 文件探针
* 当父目录不存在时,创建目录!
*
* @param dirFile 目录文件
*/
private static void fileProber(File dirFile) {
File parentFile = dirFile.getParentFile();
if (!parentFile.exists()) {
// 递归寻找上级目录
fileProber(parentFile);
parentFile.mkdir();
}
}
/**
* 解压缩文件
* @param destFile 目标文件
* @param zis Zip输入流
* @throws IOException IO异常
*/
private static void decompressFile(File destFile, ZipInputStream zis) throws IOException {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
int count;
byte[] data = new byte[BUFFER_SIZE * bufferCoefficient];
while ((count = zis.read(data, 0, BUFFER_SIZE * bufferCoefficient)) != -1) {
bos.write(data, 0, count);
}
bos.close();
}
}