最近碰到个文件下载的需求:需要实现单个文件的下载、批量文件的下载、文件夹的打包下载、批量文件夹的打包下载;
于是在网上找很多方法。但是总有各种问题。因此就自己总结写了个工具类,同时解决了中文乱码问题。
这个工具类的功能为:
-
-
- (1)可以压缩文件,也可以压缩文件夹
- (2)同时支持压缩多级文件夹,工具内部做了递归处理
- (3)碰到空的文件夹,也可以压缩
- (4)单个、批量文件、文件夹的压缩
- (5)解压文件
-
使用的jar: ant-1.8.2.jar (当然,其他版本的也可以)
下载链接:ant-1.8.2.jar
实现代码:
package com.common.utils.files;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
/**
* 文件压缩和解压的工具类
* @author zhh
* 2018-12-26
*/
public class MyFileUtils {
/**
* 编码格式
*/
private static final String encoding = "GBK";
/**
* 功能:批量压缩(文件或者文件夹)
* @param srcPathList: 文件路径集合例如: (文件:E:\\car\\a.txt、文件夹:E:\\car\\A)
* @param zipPath: 压缩后的文件路径 例:"E:\\car\\empty.zip"
* @return
*/
public static boolean zipBatchFileWithTier(List<String> srcPathList,String zipPath) {
boolean flag = true; // 标识,true:成功,false:失败
System.out.println("压缩后的文件:"+zipPath);
ZipOutputStream out = null;
BufferedOutputStream buffer = null;
FileOutputStream zipFile = null;
try {
zipFile = new FileOutputStream(zipPath);
buffer = new BufferedOutputStream(zipFile);
out = new ZipOutputStream(buffer);
out.setEncoding(encoding); // 设置编码格式,压缩和解压的编码格式保持一致
for (String filePath : srcPathList) {
zipFiles(filePath, out, "");
}
} catch (IOException e) {
flag = false;
System.out.println("压缩文件异常!");
e.printStackTrace();
}finally{
try {
if (null != out) {
out.close();
}
if (null != buffer) {
buffer.close();
}
if (null != zipFile) {
zipFile.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("压缩文件结束");
return flag;
}
/**
* 功能:压缩文件或者文件夹
* 递归指定文件还包含可能不包含任何文件的文件夹。
* @param filePath: 压缩文件路径
* @param prefix: 前缀 表示构成层关系的文件的父文件夹名。
*/
public static void zipFiles(String filePath, ZipOutputStream out, String prefix)
throws IOException {
File file = new File(filePath);
if (file.isDirectory()) { // 文件目录
if (file.listFiles().length == 0) {
ZipEntry zipEntry = new ZipEntry(prefix + file.getName() + "/");
out.putNextEntry(zipEntry);
out.closeEntry();
} else {
prefix += file.getName() + File.separator;
for (File f : file.listFiles())
zipFiles(f.getAbsolutePath(), out, prefix);
}
} else { // 文件
FileInputStream in = null;
ZipEntry zipEntry = null;
try {
in = new FileInputStream(file);
zipEntry = new ZipEntry(prefix + file.getName());
out.putNextEntry(zipEntry);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally { // 关闭流
if (null != out) {
try {
out.closeEntry();
} catch (Exception e2) {
e2.printStackTrace();
}
}
if (null != in) {
in.close();
}
}
}
}
/**
* 解压文件
* @param sourceZip: zip文件路径
* @param destDir: 解压后的文件路径
* @throws Exception
*/
private static void unZipFiles(String sourceZip,String destDir) throws Exception{
try{
Project p = new Project();
Expand expand = new Expand();
expand.setProject(p);
expand.setSrc(new File(sourceZip));
expand.setOverwrite(false);
expand.setDest(new File(destDir));
expand.setEncoding(encoding); // 设置编码格式,压缩和解压的编码格式保持一致
expand.execute();
}catch(Exception e){
throw e;
}
}
public static void main(String[] args) throws Exception {
List<String> list = new ArrayList<String>();
list.add("E:\\car\\yaun3"); // 需要压缩的文件夹
list.add("E:\\car\\A1\\压缩测试文件.txt"); // 需要压缩的文件
String zipPath2 = "E:\\car\\cs.zip";
zipBatchFileWithTier(list,zipPath2); // 压缩
unZipFiles(zipPath2,"E:\\car\\A3");
}
}
主要使用了apache的工具类。