今天遇到了 文件打包成zip的问题, 用的以前的方法发现不能解压win10系统生成的压缩包,而且压缩文件时有些文件不能压缩。
于是参考了一个新的方法,用于分享,做个笔记
1、需要依赖 ant-*.jar
2、写一个 ZipUtil 工具类即可
package com.chinagdn.chengh.util;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class ZipUtil {
/**
* 使用GBK编码可以避免压缩中文文件名乱码
*/
private static final String CHINESE_CHARSET = "GBK";
/**
* 文件读取缓冲区大小
*/
private static final int CACHE_SIZE = 1024;
private ZipUtil() {
// 私用构造主法.因为此类是工具类.
}
/**
* <p>
* 压缩文件
* </p>
*
* @param sourceFolder
* 需压缩文件 或者 文件夹 路径
* @param zipFilePath
* 压缩文件输出路径
* @throws Exception
*/
public static void zip(String sourceFolder, String zipFilePath) throws Exception {
OutputStream out = new FileOutputStream(zipFilePath);
BufferedOutputStream bos = new BufferedOutputStream(out);
org.apache.tools.zip.ZipOutputStream zos = new org.apache.tools.zip.ZipOutputStream(bos);
// 解决中文文件名乱码
zos.setEncoding(CHINESE_CHARSET);
File file = new File(sourceFolder);
String basePath = null;
if (file.isDirectory()) {
basePath = file.getPath();
} else {
basePath = file.getParent();
}
zipFile(file, basePath, zos);
zos.closeEntry();
zos.close();
bos.close();
out.close();
}
/**
* <p>
* 压缩文件
* </p>
*
* @param sourceFolders
* 一组 压缩文件夹 或 文件
* @param zipFilePath
* 压缩文件输出路径
* @throws Exception
*/
public static void zip(String[] sourceFolders, String zipFilePath) throws Exception {
OutputStream out = new FileOutputStream(zipFilePath);
BufferedOutputStream bos = new BufferedOutputStream(out);
org.apache.tools.zip.ZipOutputStream zos = new org.apache.tools.zip.ZipOutputStream(bos);
// 解决中文文件名乱码
zos.setEncoding(CHINESE_CHARSET);
for (int i = 0; i < sourceFolders.length; i++) {
File file = new File(sourceFolders[i]);
String basePath = null;
basePath = file.getParent();
zipFile(file, basePath, zos);
}
zos.closeEntry();
zos.close();
bos.close();
out.close();
}
/**
* <p>
* 递归压缩文件
* </p>
*
* @param parentFile
* @param basePath
* @param zos
* @throws Exception
*/
private static void zipFile(File parentFile, String basePath, org.apache.tools.zip.ZipOutputStream zos)
throws Exception {
File[] files = new File[0];
if (parentFile.isDirectory()) {
files = parentFile.listFiles();
} else {
files = new File[1];
files[0] = parentFile;
}
String pathName;
InputStream is;
BufferedInputStream bis;
byte[] cache = new byte[CACHE_SIZE];
for (File file : files) {
if (file.isDirectory()) {
basePath = basePath.replace('\\', '/');
if (basePath.substring(basePath.length() - 1).equals("/")) {
pathName = file.getPath().substring(basePath.length()) + "/";
} else {
pathName = file.getPath().substring(basePath.length() + 1) + "/";
}
zos.putNextEntry(new org.apache.tools.zip.ZipEntry(pathName));
zipFile(file, basePath, zos);
} else {
pathName = file.getPath().substring(basePath.length());
pathName = pathName.replace('\\', '/');
if (pathName.substring(0, 1).equals("/")) {
pathName = pathName.substring(1);
}
is = new FileInputStream(file);
bis = new BufferedInputStream(is);
zos.putNextEntry(new org.apache.tools.zip.ZipEntry(pathName));
int nRead = 0;
while ((nRead = bis.read(cache, 0, CACHE_SIZE)) != -1) {
zos.write(cache, 0, nRead);
}
bis.close();
is.close();
}
}
}
/**
* 解压文件到指定目录
*/
public static void unZipFiles(File zipFile, String descDir) throws IOException {
File pathFile = new File(descDir);
if (!pathFile.exists()) {
pathFile.mkdirs();
}
// 解决zip文件中有中文目录或者中文文件
ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));
for (Enumeration entries = zip.entries(); entries.hasMoreElements();) {
ZipEntry entry = (ZipEntry) entries.nextElement();
String zipEntryName = entry.getName();
InputStream in = zip.getInputStream(entry);
String outPath = (descDir + zipEntryName).replaceAll("\\*", "/");
// 判断路径是否存在,不存在则创建文件路径
File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
if (!file.exists()) {
file.mkdirs();
}
// 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
if (new File(outPath).isDirectory()) {
continue;
}
OutputStream out = new FileOutputStream(outPath);
byte[] buf1 = new byte[1024];
int len;
while ((len = in.read(buf1)) > 0) {
out.write(buf1, 0, len);
}
in.close();
out.close();
}
zip.close();
}
}
3、调用 zip()
、unZipFiles() 即可实现打包和解压
public static void main(String[] args) throws Exception {
File zipFile = new File("F:/downLoad/test.zip");
String path = "F:/ChromeDownloads/";
ZipUtil.unZipFiles(zipFile, path); //解压
// ZipUtil.zip("f:/download/附件", "f:/download/test.zip"); 打包
}
4、如果你需要打包的文件不在同一个文件夹
-
创建一个临时文件夹,用于打包
-
File dirTemp = new File("d://临时文件夹"); if ((!dirTemp.exists()) && (!dirTemp.isDirectory())) { dirTemp.mkdirs(); }
-
使用 commons-io 的工具类将文件复制到 临时文件夹下
-
//FileUtils.copyFileToDirectory(File srcFile, File destDir); // 将 1.txt 移动到 D盘/临时文件夹 FileUtils.copyFileToDirectory(new File("c://1.txt"), new File("d://临时文件夹")); FileUtils.copyFileToDirectory(new File("f://2.txt"), new File("d://临时文件夹"));
-
使用自己写的工具类进行打包
-
//zip(String sourceFolder, String zipFilePath) // 将临时文件夹下面的文件打包到 test.zip下 ZipUtil.zip("d://临时文件夹", "d://test.zip"); FileUtils.deleteDirectory(new File("d://临时文件夹")); //删除临时文件