Java实现 Zip打包压缩第二弹 从String直接变Zip压缩文件
2020-01-10
阅读 {{counts.readCount}}
评论 {{counts.commentCount}}
## 前言
之前实现过一版Java的zip
链接:[https://leanote.zzzmh.cn/blog/post/5cac404e16199b2e40000035](https://leanote.zzzmh.cn/blog/post/5cac404e16199b2e40000035)
之前这一版针对的是文件或者文件夹,压缩成Zip压缩包。
这个和服务器上在线生成压缩包的需求有点出入。
服务器上的内容是存数据库的,如果要先产生一个`临时文件`,
再压缩成Zip,就会产生很多临时文件,需要在写清理脚本,设计上不合理。
在研究了Java8内置的zip包后,发现其实他本质就是一个`OutputStream`
所以理论上其实可以直接把String作为文本的内容压到Zip中的文件里,文件的路径和文件名都可以按需求指定
## 代码
```java
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* @author zmh
* @date 2020-01-07
* <p>
* 文件流转压缩包工具类
*/
public class ZipUtils {
/**
* 缓存区大小
*/
private static final int BUFFER_SIZE = 2 * 1024;
/**
* 压缩核心方法
*/
private static void compress(ZipOutputStream zos, String path, String name, String data) throws Exception {
byte[] buf = new byte[BUFFER_SIZE];
zos.putNextEntry(new ZipEntry(path + name));
int len;
ByteArrayInputStream in = new ByteArrayInputStream(data.getBytes(GzipUtils.GZIP_ENCODE_UTF_8));
while ((len = in.read(buf)) != -1) {
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
}
/**
* 文本直接转zip压缩成文件
*
* @param list -> map -> path 路径; name 文件名; data 具体文本内容;
* @param out 传入输出流
* @throws RuntimeException 抛出异常
*/
public static void toZip(List<Map<String, String>> list, OutputStream out) throws RuntimeException {
ZipOutputStream zos = null;
try {
zos = new ZipOutputStream(out);
for (Map<String, String> map : list) {
String path = map.get("path");
String name = map.get("name");
String data = map.get("data");
compress(zos, path, name, data);
}
} catch (Exception e) {
throw new RuntimeException("zip error from ZipUtils", e);
} finally {
if (zos != null) {
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws Exception {
List<Map<String, String>> list = new ArrayList<>();
OutputStream outputStream = new FileOutputStream(new File("/home/zzzmh/Desktop/临时文件/test.zip"));
Map<String,String> m1 = new HashMap(){{put("path","/f1/f2/f3/");put("name","1.txt");put("data","abcdefg");}};
Map<String,String> m2 = new HashMap(){{put("path","/f1/f2/f3/f4/");put("name","2.txt");put("data","abcdefg");}};
Map<String,String> m3 = new HashMap(){{put("path","");put("name","3.txt");put("data","abcdefg");}};
list.add(m1);
list.add(m2);
list.add(m3);
toZip(list, outputStream);
if (outputStream != null) {
outputStream.close();
}
}
}
```
## 结果

## END
补充:这里传入的参数OutputStream,可以用于生成本地文件的`FileOutputStream` ,也可以用于`HttpServletResponseresponse`里的 `ServletOutputStream` 用于网页端直接文件流下载