一、使用工具
* java.utils 下的ZipOutputStream
* java.net 的http请求工具 HttpURLConnection
二、 zip下载
1. 通过浏览器以附件的形式下载到客户端
思路:
response 的write方法要写出一个byte[],所以我们需要从ZipStreamOutputStream中获取到byte[]。 在java中从io流中获取byte的办法就是将
io流写到字节数组输出流中ByteArrayOutputStream(即内存中)。 代码如下:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ZipStreamOutputStream zos = new ZipStreamOutputStream(bos)
byte[] data = bos.toByteArray();
分析数据流流向如下:
图片字节数据byte[](jpg) --> ZipStreamOutputStream --> ByteArrayOutputStream -> byte[](zip)
2. 下载到服务器文件目录下
分析数据流流向如下:
图片字节数据byte[](jpg) --> ZipStreamOutputStream --> FileOutputStream -> File(zip)
三、 注意点
1. 在向ZipOutputStream中写完数据后,必须马上关闭ZipOutputStream,否则zip文件会损坏
2. 对于包装流,关闭流的顺序问题
一层套一层的包装流,关闭顺序一定是先关闭外层包装流,然后再关闭内层的流,否则会文件损坏,而且在关闭外层流的时候会报流已经关闭异常
四、 实践代码
`
@GetMapping("/getImage")
public void imageDownloadServer(HttpServletResponse response, String imgType) throws IOException {
response.setContentType("text/plain");
ServletOutputStream outputStream = response.getOutputStream();
BASE64Encoder encoder = new BASE64Encoder();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
File file = null;
if ("F".equals(imgType)) {
file = new File("C:\\Users\\cheva\\Desktop\\票样\\1.jpg");
} else {
file = new File("C:\\Users\\cheva\\Desktop\\票样\\2.jpg");
}
InputStream fis = new FileInputStream(file);
int len = -1;
byte[] buff = new byte[1024];
while ((len = fis.read(buff)) != -1) {
bos.write(buff, 0, len);
}
bos.flush();
String base64 = encoder.encode(bos.toByteArray());
fis.close();
bos.close();
outputStream.write(base64.getBytes(StandardCharsets.UTF_8));
outputStream.flush();
outputStream.close();
}
@GetMapping("/download")
public void dowload(HttpServletRequest request, HttpServletResponse response) {
ByteArrayOutputStream bos = null;
ZipOutputStream zipOutputStream = null;
String outName = "my.zip";
try {
bos = new ByteArrayOutputStream();
zipOutputStream = new ZipOutputStream(bos);
packageZipStream("0011", zipOutputStream);
} catch (Exception e) {
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
try {
ServletOutputStream os = response.getOutputStream();
os.write(e.getMessage().getBytes());
os.flush();
} catch (IOException ioException) {
ioException.printStackTrace();
}
} finally {
if (zipOutputStream != null) {
try {
zipOutputStream.close();
} catch (Exception e) {
System.out.println("zip输出流关闭异常");
}
}
if (bos != null) {
try {
bos.close();
} catch (Exception e) {
System.out.println("流关闭异常");
}
}
}
try {
response.setContentType("application/zip");
response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(outName, "UTF-8"));
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(bos.toByteArray());
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
@GetMapping("/downloadLoc")
public void downloadLoc(HttpServletResponse response) {
FileOutputStream fis = null;
ZipOutputStream zipOutputStream = null;
try {
File file = new File("D:\\Compressed\\my.zip");
if (!file.getParentFile().exists()) {
file.getParentFile().mkdir();
}
fis = new FileOutputStream(file);
zipOutputStream = new ZipOutputStream(fis);
packageZipStream("0011", zipOutputStream);
} catch (Exception e) {
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
try {
ServletOutputStream os = response.getOutputStream();
os.write(e.getMessage().getBytes());
os.flush();
} catch (IOException ioException) {
ioException.printStackTrace();
}
} finally {
if (zipOutputStream != null) {
try {
zipOutputStream.close();
} catch (Exception e) {
System.out.println("流关闭异常");
}
}
if (fis != null) {
try {
fis.close();
} catch (Exception e) {
System.out.println("流关闭异常");
}
}
}
}
private void packageZipStream(String imgId, ZipOutputStream zos) {
String path = null;
try {
if (zos == null || imgId == null) {
return;
}
path = imgId + File.separator + "正面.jpg";
zos.putNextEntry(new ZipEntry(path));
byte[] data = downloadImageFromURL("http://localhost:8098/chat-server/test/getImage?imgType=F");
zos.write(data, 0, data.length);
zos.closeEntry();
path = imgId + File.separator + "反面.jpg";
zos.putNextEntry(new ZipEntry(path));
data = downloadImageFromURL("http://localhost:8098/chat-server/test/getImage?imgType=B");
zos.write(data, 0, data.length);
zos.closeEntry();
} catch (Exception e) {
if (e instanceof ZipException) {
throw new RuntimeException(path + "重名,只进行一次下载处理");
} else {
throw new RuntimeException(e.getMessage());
}
}
}
private byte[] downloadImageFromURL(String urlPath) {
HttpURLConnection conn = null;
InputStream is = null;
byte[] data = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
URL url = new URL(urlPath);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(6000);
conn.setDoInput(true);
is = conn.getInputStream();
if (conn.getResponseCode() == 200) {
byte[] buff = new byte[1024];
int len = -1;
while ((len = is.read(buff)) != -1) {
bos.write(buff, 0, len);
}
bos.flush();
data = bos.toByteArray();
BASE64Decoder decoder = new BASE64Decoder();
data = decoder.decodeBuffer(new String(data));
} else {
data = null;
}
} catch (Exception e) {
throw new RuntimeException("连接服务器异常");
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return data;
}`
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程