Java实现压缩解压文件
关键词:ZipOutputStream ZipInoutStream
最近在工作中有需求需要在浏览器中一次性下载多个文件,于是想到了使用压缩的功能。百度了一下,发现很多博客的内容都大致相同,不太方便使用。于是自己写了这么一个工具类,使用JDK中自带的ZipOutputStream和ZipInoutStream实现对文件的压缩和解压。
█ 源码
/**
* 使用方法:
* byte[] bytes = ZipUtil.createZipObject().addFile(fileBytes, "hello.xls").create();
*
* 需要添加多个文件就调用多次addFile,最后调用create生成字节数组即可
*
*/
public class ZipUtil {
private ZipUtil() {
throw new RuntimeException("Illegal operation");
}
// 压缩文件
public static ZipObject createZipObject() {
return new ZipObject();
}
// 解压文件,参数是压缩文件字节数组
public static UnZipObject createUnZipObject(byte[] bytes) {
if (bytes==null || bytes.length==0) {
throw new IllegalArgumentException("bytes is null");
}
return new UnZipObject(bytes);
}
public static class ZipObject {
// 工具流
private ZipOutputStream zos;
// 使用带有缓冲功能的文件流存储文件
private ByteArrayOutputStream bos;
private ZipObject() {
bos = new ByteArrayOutputStream();
// 文件数据流实际存储在了bos
zos = new ZipOutputStream(bos);
}
/**
* 添加一个文件到压缩包中
* @param fileBytes 文件的字节数组
* @param fileName 文件名,带文件类型的,比如:hello.xlsx
* @return
*/
public ZipObject addFile(byte[] fileBytes, String fileName) {
try {
// 可以理解一个ZipEntry就表示压缩包里面的一个文件
ZipEntry zipEntry = new ZipEntry(fileName);
zos.putNextEntry(zipEntry);
zos.write(fileBytes, 0, fileBytes.length);
} catch (IOException e) {
if (bos!=null) {
try {
bos.close();
} catch (IOException ee){}
}
if (zos!=null) {
try {
zos.close();
} catch (IOException ee){}
}
}
return this;
}
/**
* 生成压缩包的字节数组
* @return
*/
public byte[] create() {
byte[] bytes = null;
try {
// 将数据写到ByteArrayOutputStream中
zos.finish();
bytes = bos.toByteArray();
bos.flush();
zos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bos!=null) {
try {
bos.close();
} catch (IOException e){}
}
if (zos!=null) {
try {
zos.close();
} catch (IOException e){}
}
}
return bytes;
}
}
public static class UnZipObject {
// 工具流
private ZipInputStream zis;
// 使用带有缓冲功能的文件流存储文件
private ByteArrayInputStream bis;
private int size;
private UnZipObject(byte[] bytes) {
size = bytes.length;
bis = new ByteArrayInputStream(bytes);
// 文件数据流实际存储在了bos
zis = new ZipInputStream(bis);
}
/**
* 获取压缩包里面的文件,一个ZipEntry表示一个文件
* @return
*/
public List<ZipEntry> getEntrys() {
List<ZipEntry> list = new ArrayList<>();
try {
ZipEntry nextEntry = zis.getNextEntry();
// 一个个循环读取压缩文件中的内容,放进bytes数组中
while (nextEntry!=null) {
byte[] bytes = new byte[size];
zis.read(bytes);
nextEntry.setExtra(bytes);
list.add(nextEntry);
nextEntry = zis.getNextEntry();
}
} catch (IOException e) {
e.printStackTrace();
if (bis!=null) {
try {
bis.close();
} catch (IOException ee){}
}
if (zis!=null) {
try {
zis.close();
} catch (IOException ee){}
}
}
return list;
}
}
}
█ 使用
压缩打包文件:
public class ZipUtilTest {
@Test
public void testZipFile() {
try {
// 读取文件1
File file1 = new File("E:\\project\\java\\src\\main\\resources\\zip\\zip1.text");
FileInputStream fis1 = new FileInputStream(file1);
byte[] fileBytes1 = new byte[fis1.available()];
fis1.read(fileBytes1);
// 读取文件2
File file2 = new File("E:\\project\\java\\src\\main\\resources\\zip\\zip2.text");
FileInputStream fis2 = new FileInputStream(file1);
byte[] fileBytes2 = new byte[fis2.available()];
fis2.read(fileBytes2);
// 获取压缩包文件字节数组
byte[] bytes = ZipUtil.createZipObject().addFile(fileBytes1, file1.getName()).addFile(fileBytes2, file2.getName()).create();
/**
* 如果是响应给浏览器的话,可以:
* HttpServletResponse.getOutputStream().write(bytes[]);
*/
// 将压缩包数据写到本地
FileOutputStream fos = new FileOutputStream("E:\\project\\java\\src\\main\\resources\\zip\\hello.zip");
fos.write(bytes);
} catch (Exception e) {
e.printStackTrace();
}
}
}
解压压缩包中的文件:
@Test
public void testUnZipFile() {
try {
// 读取压缩文件
File file = new File("E:\\project\\java\\src\\main\\resources\\zip\\hello.zip");
FileInputStream fis1 = new FileInputStream(file);
byte[] fileBytes1 = new byte[fis1.available()];
fis1.read(fileBytes1);
ZipUtil.UnZipObject unZipObject = ZipUtil.createUnZipObject(fileBytes1);
List<ZipEntry> entryList = unZipObject.getEntrys();
System.out.println("entryList:"+entryList.size());
entryList.forEach(zipEntry -> {
try {
// zipEntry.getName() 压缩包里面的文件名
FileOutputStream fos = new FileOutputStream("E:\\project\\"+zipEntry.getName());
// zipEntry.getExtra()是压缩包里面的一个个文件数据
fos.write(zipEntry.getExtra());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
还没有评论,来说两句吧...