生成压缩包的多种方式——Java【上】

时间:2022-12-05 18:56:27

天气好冷,不想敲代码呀呀呀~

生成压缩包的多种方式——Java【上】

日子还在继续,工作不能停!开始今天正题——文件操作【生成压缩包】如何生成压缩包呢?作为一个后端开发入门的打工人,首先想到还是用后端方式去解决。

说到后端,推荐一个比较厉害的Maven依赖,我以前好像也推荐过,不过没关系,再推荐一遍!​​文档说明链接​

        <dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.10</version>
</dependency>

​​​​讲真!人家还是真的有封装好哦!​​压缩工具链接​​ 

生成压缩包的多种方式——Java【上】

超级好用!看完案例感觉好像很清楚,不需要额外写啥了...【要我啥用】

package com.example.tool.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;


@RestController
@RequestMapping("/util")
public class UtilController {
private static final Log logger = LogFactory.getLog(UtilController.class);

@ApiOperation(value = "本地文件压缩", notes = "文件压缩成压缩包")
@RequestMapping(value = "/zipLocalFile", method = RequestMethod.GET)
public void zipLocalFile(HttpServletResponse response) throws UnsupportedEncodingException {
String localFileUrl = "e:/test.zip";
ZipUtil.zip(FileUtil.file(localFileUrl), false,
FileUtil.file("e:/txt1.txt"),
FileUtil.file("e:/txt2.txt")
);

BufferedInputStream bufferedInputStream = null;
ServletOutputStream servletOutputStream = null;

try {
bufferedInputStream = new BufferedInputStream(new FileInputStream(localFileUrl));
servletOutputStream = response.getOutputStream();
int len;
byte[] bytes = new byte[1024 * 2];
while ((len = bufferedInputStream.read(bytes)) != -1) {
servletOutputStream.write(bytes, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedInputStream != null) {
bufferedInputStream.close();
}
if (servletOutputStream != null) {
servletOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
response.setContentType("application/octet-stream; charset=UTF-8");
}


}

简单写了一个API【这样写,看起来好像有点问题】具体问题在哪先不管,反正也就看起来有点,还是可以运行,不信你自己试试咯。 现在继续接着搞,上面是保存本地文件,那如果要保存网络图片呢?

package com.example.tool.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;


@RestController
@RequestMapping("/util")
public class UtilController {
private static final Log logger = LogFactory.getLog(UtilController.class);


public static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
byte[] data = outStream.toByteArray();
outStream.close();
inStream.close();
return data;
}


public File getFile(String fileUrl, String fileName) {
// fileName文件名处理
if (fileName.contains("/")) {
fileName = fileName.replace("/", "-");
}
fileName = "e:/" + fileName;
File imageFile = null;
try {
//定义一个URL对象,就是你想下载的URL地址
URL url = new URL(fileUrl);
//打开连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置请求方式为"GET"
conn.setRequestMethod("GET");
//超时响应时间为10秒
conn.setConnectTimeout(10 * 1000);
//通过输入流获取数据
InputStream is = conn.getInputStream();
//得到二进制数据,以二进制封装得到数据,具有通用性
byte[] data = readInputStream(is);
//创建一个文件对象用来保存
imageFile = new File(fileName);
//创建输出流
FileOutputStream outStream = new FileOutputStream(imageFile);
//写入数据
outStream.write(data);
//关闭输出流,释放资源
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}

return imageFile;
}


@ApiOperation(value = "本地文件压缩", notes = "文件压缩成压缩包")
@RequestMapping(value = "/zipLocalFile", method = RequestMethod.GET)
public void zipLocalFile(HttpServletResponse response) throws UnsupportedEncodingException {
String imgUrl = "https://pic.netbian.com/uploads/allimg/221201/005454-1669827294d312.jpg";

String localFileUrl = "e:/test.zip";
ZipUtil.zip(FileUtil.file(localFileUrl), false,
FileUtil.file("e:/txt1.txt"),
FileUtil.file("e:/txt2.txt"),
FileUtil.file(getFile(imgUrl, "img-test.jpg"))
);

BufferedInputStream bufferedInputStream = null;
ServletOutputStream servletOutputStream = null;

try {
bufferedInputStream = new BufferedInputStream(new FileInputStream(localFileUrl));
servletOutputStream = response.getOutputStream();
int len;
byte[] bytes = new byte[1024 * 2];
while ((len = bufferedInputStream.read(bytes)) != -1) {
servletOutputStream.write(bytes, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedInputStream != null) {
bufferedInputStream.close();
}
if (servletOutputStream != null) {
servletOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
response.setContentType("application/octet-stream; charset=UTF-8");
}

}

加了getFile和readInputStream后,突然代码量就上来了,要命!看起来变得有点复杂了。

仔细看看,发现好像又一丢丢问题!

问题一:getFile先把网络图片保存到本地,要是不想保存本地呢?

问题二:请求接口时,ZipUtil.zip已经生成e:/test.zip,但是又会通过response响应文件流给前端,浏览器再下载一份zip文件。

问题好多!我为什么要这样搞【救命~】要放服务器上的,这样额外保存一份,磁盘空间都不够诶【偷偷说:不管够不够,反正敢这样搞,怕是会被打死】

package com.example.tool.controller;

import cn.hutool.core.io.FastByteArrayOutputStream;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.core.util.ZipUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


@RestController
@RequestMapping("/util")
public class UtilController {
private static final Log logger = LogFactory.getLog(UtilController.class);


public static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
byte[] data = outStream.toByteArray();
outStream.close();
inStream.close();
return data;
}


public File getFile(String fileUrl, String fileName) {
// fileName文件名处理
if (fileName.contains("/")) {
fileName = fileName.replace("/", "-");
}
fileName = "e:/" + fileName;
File imageFile = null;
try {
//定义一个URL对象,就是你想下载的URL地址
URL url = new URL(fileUrl);
//打开连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置请求方式为"GET"
conn.setRequestMethod("GET");
//超时响应时间为10秒
conn.setConnectTimeout(10 * 1000);
//通过输入流获取数据
InputStream is = conn.getInputStream();
//得到二进制数据,以二进制封装得到数据,具有通用性
byte[] data = readInputStream(is);
//创建一个文件对象用来保存
imageFile = new File(fileName);
//创建输出流
FileOutputStream outStream = new FileOutputStream(imageFile);
//写入数据
outStream.write(data);
//关闭输出流,释放资源
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}

return imageFile;
}


@ApiOperation(value = "本地文件压缩", notes = "文件压缩成压缩包")
@RequestMapping(value = "/zipLocalFile", method = RequestMethod.GET)
public void zipLocalFile(HttpServletResponse response) throws UnsupportedEncodingException {
String imgUrl = "https://pic.netbian.com/uploads/allimg/221201/005454-1669827294d312.jpg";

String localFileUrl = "e:/test.zip";
ZipUtil.zip(FileUtil.file(localFileUrl), false,
FileUtil.file("e:/txt1.txt"),
FileUtil.file("e:/txt2.txt"),
FileUtil.file(getFile(imgUrl, "img-test.jpg"))
);

BufferedInputStream bufferedInputStream = null;
ServletOutputStream servletOutputStream = null;

try {
bufferedInputStream = new BufferedInputStream(new FileInputStream(localFileUrl));
servletOutputStream = response.getOutputStream();
int len;
byte[] bytes = new byte[1024 * 2];
while ((len = bufferedInputStream.read(bytes)) != -1) {
servletOutputStream.write(bytes, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedInputStream != null) {
bufferedInputStream.close();
}
if (servletOutputStream != null) {
servletOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
response.setContentType("application/octet-stream; charset=UTF-8");
}


@ApiOperation(value = "网络文件压缩", notes = "压缩文件成压缩包")
@RequestMapping(value = "/zipNetworkFile", method = RequestMethod.GET)
public void zipNetworkFile(HttpServletResponse response) throws IOException {

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream);

String imgUrl = "https://pic.netbian.com/uploads/allimg/221201/005454-1669827294d312.jpg";
try {
URL url3 = new URL(imgUrl);
InputStream stream = URLUtil.getStream(url3);
FastByteArrayOutputStream read = IoUtil.read(stream);
byte[] bytesImg = read.toByteArray();
zipOutputStream.putNextEntry(new ZipEntry(FileUtil.getName("img-test.jpg")));
zipOutputStream.write(bytesImg);
IOUtils.closeQuietly(read);
zipOutputStream.flush();
zipOutputStream.closeEntry();
} catch (IOException e) {
logger.warn("下载失败");
}
IOUtils.closeQuietly(zipOutputStream);
byte[] bytes = byteArrayOutputStream.toByteArray();

// 由响应response直接输入到前端
response.reset();
response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("test.zip", "UTF-8"));
response.addHeader("Content-Length", "" + bytes.length);
response.setContentType("application/octet-stream; charset=UTF-8");
IOUtils.write(bytes, response.getOutputStream());
}


}

zipNetworkFile看起来顺眼多了,但是图片量大会不会有点问题?如果我要给压缩包设置压缩密码怎么搞呢?