最近工作中需要生成指定的多层文件目录,然后把文件压缩打包下载,当时对这方面的知识并不熟悉,所以花了大量时间来调试程序,目前处理好了mark以下,以方便自己以后查看,直接上代码了:
这是工作中用到的zip打包工具类
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public final class FileToZip {
private FileToZip() {
}
/**
* 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件,并存放到zipFilePath路径下
*
* @param sourceFilePath :待压缩的文件路径
* @param zipFilePath :压缩后存放路径
* @param fileName :压缩后文件的名称
* @return
* @throws IOException
*/
public static boolean fileToZip(String sourceFilePath, String zipFilePath, String fileName) throws IOException {
boolean flag = false;
File sourceFile = new File(sourceFilePath);
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
ZipOutputStream zos = null;
if (sourceFile.exists() == false) {
System.out.println("待压缩的文件目录:" + sourceFilePath + "不存在.");
} else {
try {
File zipFile = new File(zipFilePath + fileName + ".zip");
if (zipFile.exists()) {
System.out.println(zipFilePath + "目录下存在名字为:" + fileName + ".zip" + "打包文件.");
} else {
File[] sourceFiles = sourceFile.listFiles();
if (null == sourceFiles || sourceFiles.length < 1) {
System.out.println("待压缩的文件目录:" + sourceFilePath + "里面不存在文件,无需压缩.");
} else {
fos = new FileOutputStream(zipFile);
zos = new ZipOutputStream(new BufferedOutputStream(fos));
byte[] bufs = new byte[1024 * 10];
addFile(sourceFile, zos, fis, bis, bufs, zipFilePath.substring(0, zipFilePath.length() - 1));
flag = true;
if (null != zos) {
zos.closeEntry();
zos.close();
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
//关闭流
try {
if (null != fis) {
fis.close();
}
if (null != fos) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
return flag;
}
/**
* 遍历文件夹,放到zip输出流中去
* @param source
* @param zos
* @param fis
* @param bis
* @param bufs
* @throws IOException
*/
private static void addFile(File source, ZipOutputStream zos, FileInputStream fis, BufferedInputStream bis, byte[] bufs, String basePath) throws IOException {
File[] childes = source.listFiles();
for (File file : childes) {
if (file.isFile()) {
//创建ZIP实体,并添加进压缩包
ZipEntry zipEntry = new ZipEntry(StringUtils.remove(file.getAbsolutePath(), basePath).substring(1));
zos.putNextEntry(zipEntry);//子文件名称不能相同,会报错
//读取待压缩的文件并写进压缩包里
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis, 1024 * 10);
int read = 0;
while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
zos.write(bufs, 0, read);
}
if (null != bis) {
bis.close();
}
} else {
addFile(file, zos, fis, bis, bufs, basePath);
}
}
}
/**
* 迭代删除文件夹
*
* @param dirPath 文件夹路径
*/
public static void deleteDir(String dirPath) {
File file = new File(dirPath);
if (file.isFile()) {
file.delete();
} else {
File[] files = file.listFiles();
if (files == null) {
file.delete();
} else {
for (int i = 0; i < files.length; i++) {
deleteDir(files[i].getAbsolutePath());
}
file.delete();
}
}
}
}
有几点需要注意下:
1.window系统下本地文件路径分隔符为"\",该工具类在取相对路径的时候已经处理了
2.addFile方法,前几行new FileEntry(String filePath)的时候如果直接用file.getName就会把所有的文件都放到一个目录下,而且如果存在同名文件会报错,所以建议用file.getAbsolutePath(),然后截取掉相对打包目录的绝对路径