压缩解压过程还是用IO流对文件的读写操作
本质还是对API的引用,代码逻辑比较简单,相关注释比较详细,请在代码中查看
代码已跑通,可自行copy测试
注:1. 在压缩文件时,传入的压缩文件路径必须是以.zip结尾的文件,否则会压缩失败
2. 解压时,在创建文件的时候注意不要将文件名也作为文件夹创建,否则会报错,原因及正确代码已贴在文章末尾
工具类
package com.lx.ZipUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
public class ZipUtils {
//压缩文件
public static void createZip(String baseDir , String zipName) throws Exception {
File baseFile = new File(baseDir);
if (baseFile.exists()){
List<File> baseFileList = getSubFiles(baseFile);
//压缩文件名及全路径zipName,以.zip结尾,创建输出流,后续文件写入该zip文件
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipName));
ZipEntry zipEntry = null;
byte[] buf = new byte[1024];
int readLen = 0;
String a = "";
//遍历所有文件并读取,写到zipOutputStream中
for (File file : baseFileList) {
//创建ZipEntry
//System.out.println(getFileName(baseDir,file)+" "+baseDir+" "+file);
zipEntry = new ZipEntry(getAbsFileName(baseDir,file));//创建ZipEntry对象,参数为各文件在源文件的相对路径(在压缩文件中保留)
//zipEntry = new ZipEntry(file.getName());//直接压缩,不保留原相对路径
zipEntry.setSize(file.length());//设置文件大小
zipEntry.setTime(file.lastModified());//读取文件的最后修改时间,作为压缩文件中文件的修改时间
//将ZipEntry放到ZipOutputStream中(ZipEntry相当于在压缩文件中创建对应文件的空间,后续将读取的内容写到该位置)
zipOutputStream.putNextEntry(zipEntry);
/*BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file),"utf-8"));//纯文本文件外会乱码
while((a = reader.readLine())!=null){
zipOutputStream.write(a.getBytes());
}
reader.close();*/
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
while((readLen = inputStream.read(buf,0,1024))!=-1){
zipOutputStream.write(buf,0,readLen);
}
inputStream.close();
}
zipOutputStream.close();
}else {
throw new Exception("文件夹不存在");
}
}
//解压文件
public static void releaseZip(String sourceZip , String outFileName) throws IOException {
ZipFile zipFile = new ZipFile(sourceZip);
Enumeration<? extends ZipEntry> zipList = zipFile.entries();
ZipEntry zipEntry = null;
int readLen = 0;
byte[] buf = new byte[1024];
while(zipList.hasMoreElements()){
zipEntry = zipList.nextElement();
if (zipEntry.isDirectory()){
continue;
}
BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(zipEntry));
System.out.println(zipEntry.getName());
System.out.println(getRealFile(outFileName, zipEntry.getName()));
BufferedOutputStream bos =
new BufferedOutputStream(new FileOutputStream(getRealFile(outFileName, zipEntry.getName())));
while ((readLen = bis.read(buf,0,1024))!=-1){
bos.write(buf,0,readLen);
}
bos.close();
bis.close();
}
}
//遍历给定文件夹中的所有文件
public static List<File> getSubFiles(File baseFile){
List<File> baseFileList = new ArrayList<>();
File[] files = baseFile.listFiles();
for (int i = 0; i < files.length; i++) {
//是目录,加入baseFileList
if (files[i].isFile()){
baseFileList.add(files[i]);
}
//是文件,递归
if (files[i].isDirectory()){
baseFileList.addAll(getSubFiles(files[i]));
}
}
return baseFileList;
}
//给定根目录及文件全路径,返回相对路径作为压缩文件中的路径
public static String getAbsFileName(String baseDir, File realFile){
File file = realFile;
File baseFile = new File(baseDir);
String fileName = file.getName();
while(true){
file = file.getParentFile();
if (file == null){
break;
}
if (file.equals(baseFile)){
break;
}else {
fileName = file.getName()+"/"+fileName;
}
}
return fileName;
}
//根据压缩文件中的路径生成文件夹
public static File getRealFile(String outFileName , String absFileName){
String[] split = absFileName.split("/");
File realFile = new File(outFileName);
//创建目录
if (split.length > 1){
for (int i = 0 ; i < split.length-1 ; i++){//最后一位为文件,不参与文佳夹创建
realFile = new File(realFile, split[i]);
}
}
if (!realFile.exists()){
realFile.mkdirs();
}
return new File(realFile,split[split.length-1]);//在文件夹下创建文件
}
}
测试类
package com.lx.ZipUtils;
public class TestZip {
public static void main(String[] args) throws Exception {
ZipUtils.createZip("C:\\Users\\Desktop\\面试","C:\\Users\\Desktop\\0603.zip");
ZipUtils.releaseZip("C:\\Users\\Desktop\\0603.zip","D:\\解压");
}
}
测试过程中出现下面报错
原因是:在解压时,直接将文件名也作为路径创建,导致写出文件时找不到对应文件
找不到文件会报 拒绝访问
找不到文件夹回报 找不到对应路径
正确代码
错误代码