批量下载,多文件压缩打包zip下载
0、写在前面的话
1、先叨叨IO

outputStream = new FileOutputStream(file);
byte[] temp = new byte[1024];
int size = -1;
while ((size = inputStream.read(temp)) != -1) { // 每次读取1KB,直至读完
outputStream.write(temp, 0, size);
}
outputStream = new FileOutputStream(file);
byte[] temp = new byte[1024];
int size = -1;
while ((size = inputStream.read(temp)) != -1) { // 每次读取1KB,直至读完
outputStream.write(temp, 0, size);
}
2、再叨叨ajax

3、正儿八经的批量下载实现
<dependency>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
<version>1.6.5</version>
</dependency>
<dependency>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
<version>1.6.5</version>
</dependency>
/**
* 批量下载
*
* @param idxs 图片的id拼接字符串,用逗号隔开
*/
public String downloadBatch(String idxs) {
String[] ids = idxs.split(",");
try {
HttpServletResponse response = ServletActionContext.getResponse();
OutputStream out = setDownloadOutputStream(response, String.valueOf(new Date().getTime()), "zip");
ZipOutputStream zipOut = new ZipOutputStream(out);
for (int i = 0; i < ids.length; i++) {
Picture picture = Picture.get(Picture.class, Long.parseLong(ids[i]));
byte[] data = picture.getData();
zipOut.putNextEntry(new ZipEntry(i + "_" + picture.getName() + "." + picture.getFormat().getValue()));
writeBytesToOut(zipOut, data, BUFFER_SIZE);
zipOut.closeEntry();
}
zipOut.flush();
zipOut.close();
} catch (IOException e) {
e.printStackTrace();
log.warn("下载失败:" + e.getMessage());
}
return null;
}
/**
* 批量下载
*
* @param idxs 图片的id拼接字符串,用逗号隔开
*/
public String downloadBatch(String idxs) {
String[] ids = idxs.split(",");
try {
HttpServletResponse response = ServletActionContext.getResponse();
OutputStream out = setDownloadOutputStream(response, String.valueOf(new Date().getTime()), "zip");
ZipOutputStream zipOut = new ZipOutputStream(out);
for (int i = 0; i < ids.length; i++) {
Picture picture = Picture.get(Picture.class, Long.parseLong(ids[i]));
byte[] data = picture.getData();
zipOut.putNextEntry(new ZipEntry(i + "_" + picture.getName() + "." + picture.getFormat().getValue()));
writeBytesToOut(zipOut, data, BUFFER_SIZE);
zipOut.closeEntry();
}
zipOut.flush();
zipOut.close();
} catch (IOException e) {
e.printStackTrace();
log.warn("下载失败:" + e.getMessage());
}
return null;
}
/**
* 设置文件下载的response格式
*
* @param response 响应
* @param fileName 文件名称
* @param fileType 文件类型
* @return 设置后响应的输出流OutputStream
* @throws IOException
*/
private static OutputStream setDownloadOutputStream(HttpServletResponse response, String fileName, String fileType) throws IOException {
fileName = new String(fileName.getBytes(), "ISO-8859-1");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + "." + fileType);
response.setContentType("multipart/form-data");
return response.getOutputStream();
}
/**
* 设置文件下载的response格式
*
* @param response 响应
* @param fileName 文件名称
* @param fileType 文件类型
* @return 设置后响应的输出流OutputStream
* @throws IOException
*/
private static OutputStream setDownloadOutputStream(HttpServletResponse response, String fileName, String fileType) throws IOException {
fileName = new String(fileName.getBytes(), "ISO-8859-1");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + "." + fileType);
response.setContentType("multipart/form-data");
return response.getOutputStream();
}
/**
* 将byte[]类型的数据,写入到输出流中
*
* @param out 输出流
* @param data 希望写入的数据
* @param cacheSize 写入数据是循环读取写入的,此为每次读取的大小,单位字节,建议为4096,即4k
* @throws IOException
*/
private static void writeBytesToOut(OutputStream out, byte[] data, int cacheSize) throws IOException {
int surplus = data.length % cacheSize;
int count = surplus == 0 ? data.length / cacheSize : data.length / cacheSize + 1;
for (int i = 0; i < count; i++) {
if (i == count - 1 && surplus != 0) {
out.write(data, i * cacheSize, surplus);
continue;
}
out.write(data, i * cacheSize, cacheSize);
}
}
/**
* 将byte[]类型的数据,写入到输出流中
*
* @param out 输出流
* @param data 希望写入的数据
* @param cacheSize 写入数据是循环读取写入的,此为每次读取的大小,单位字节,建议为4096,即4k
* @throws IOException
*/
private static void writeBytesToOut(OutputStream out, byte[] data, int cacheSize) throws IOException {
int surplus = data.length % cacheSize;
int count = surplus == 0 ? data.length / cacheSize : data.length / cacheSize + 1;
for (int i = 0; i < count; i++) {
if (i == count - 1 && surplus != 0) {
out.write(data, i * cacheSize, surplus);
continue;
}
out.write(data, i * cacheSize, cacheSize);
}
}
- 设置文件ContentType类型和文件头
- 读取文件数据为byte[]
- 将数据写入到响应response的输出流中
- ZipOutputStream zipOut = new ZipOutputStream(out);
- //把响应的输出流包装一下而已,便于使用相关压缩方法,就像多了个包装袋
- zipOut.putNextEntry(new ZipEntry(i + "_" + picture.getName() + "." + picture.getFormat().getValue()));
- zipOut.closeEntry();
- //压缩包中的多个文件,实际上每个就是这里的ZipEntry对象,每开始写入某个文件的内容时,必须先putNextEntry(new ZipEntry(String fileName)),然后才可以写入,写完这个文件,必须使用closeEntry()说明,已经写完了第一个文件。就好像putNextEntry是在说 “我要开始写压缩包的下一个文件啦”,而closeEntry则是在说“压缩包里的这个文件我已经写完啦”。循环反复,最终把所有文件写入这个“披着压缩输出流外壳的响应输出流”
- zipOut.flush();
- 写入完成后,刷一下即可。就像去超市买东西,购物车装好了,总得结一次帐才能把东西拿走吧。当然,最后别忘了close关闭。
4、参考链接
批量下载,多文件压缩打包zip下载的更多相关文章
- 打包zip下载
//首先引入的文件为org.apache的切记不是jdk的import org.apache.tools.zip.ZipOutputStream;import org.apache.tools.zip ...
- java实现将文件压缩成zip格式
以下是将文件压缩成zip格式的工具类(复制后可以直接使用): zip4j.jar包下载地址:http://www.lingala.net/zip4j/download.php package util ...
- Web端文件打包.zip下载
使用ant.jar包的API进行文件夹打包.直接上代码: String zipfilename = "test.zip"; File zipfile = new File(zipf ...
- Linux文件压缩/打包/解压
在Linux日常维护中,经常需要备份同步一些比较重要的文件,而在传输过程中如果文件比较大往往会非常慢,而且还会非常占用空间,这时候就需要我们使用压缩工具对大文件进行压缩打包,下面我们来介绍一下常用的压 ...
- Linux中的文件压缩,打包和备份命令
压缩解压命令 gzip 文件 -c : 将压缩数据输出到屏幕,可用来重定向 -v 显示压缩比等信息 -d 解压参数 -t 用来检验一个压缩文件的一致性看看档案有没错 -数字 : 压 ...
- 文件压缩:zip
[root@localhost ~]# yum install -y zip unzip // 安装 zip 和 unzip [root@localhost ~]# ..txt // 压缩文件,要同时 ...
- Java实现多文件压缩打包的方法
package com.biao.test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutpu ...
- [转]C#如何把文件夹压缩打包然后下载
public partial class _Default2 : System.Web.UI.Page{ protected void Page_Load(object sender, EventAr ...
- Java Springboot 根据图片链接生成图片下载链接 及 多个图片打包zip下载链接
现有一些图片在服务器上的链接,在浏览器中打开这些链接是直接显示在浏览器页面的形式. 现在需要生成这些图片的单独下载以及打包下载链接,即在浏览器中打开下载链接后弹出下载框提示下载.由于前端存在跨域问题, ...
随机推荐
- DOM的查找,新增,删除操作
查找 1. document.getElementById() 通过ID获取元素,由于ID唯一,所以获取的是一个元素 2. document.getElementsByTagName() 通过标签名 ...
- Vue.js $nextTick
最近在学习vue.js.了解1.x的基础上再学习2.x的vue.两个版本的确是不会像angular这样1.x和2.x相差甚远.所以学习起来其实还是有很大的关联.但是,终归来说.两者还是有语法上的细微差 ...
- Echarts之悬浮框中的数据排序
Echarts非常强大,配置也非常的多,有很多细节需要深入研究.详解一下关于悬浮框中的数据排序问题 悬浮框的数据排序默认是根据series中的数据位置排序的,在我们想自定义排序时,在echarts的配 ...
- Android GetMethodID 函数的说明
GetFieldID是得到java类中的参数ID,GetMethodID得到java类中方法的ID,它们只能调用类中声明为 public的参数或方法.使用如下: jfieldID topicField ...
- mac下/usr/local/bin No such file or directory问题解决
在对composer进行全局配置时,执行 sudo mv composer.phar /usr/local/bin/composer 时,mac报错:/usr/local/bin No such fi ...
- Expo大作战(二十三)--expo中expo kit 高级属性(没干货)
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- [Android] Activity间切换,传递数据
前面照着android系统的裁剪图片的功能自己写了一个相似的工具.功能是大体上实现了,但留下了一个调用的问题:如何从我的程序调用这个裁剪工具,并且获得裁剪后的图片呢? 其实这个也很简单了,就是inte ...
- spring-quartz定时任务初探
最近有关定时任务的需求还蛮多的,我这里呢用的是最简单的用法,后续了解更深层次的用法来优化目前的代码. 首先就是引入相关jar quartz-1.6.4.jar spring的jar就不说了 接 ...
- 针对系统中磁盘IO负载过高的指导性操作
针对系统中磁盘IO负载过高的指导性操作 主要命令:echo deadline > /sys/block/sda/queue/scheduler 注:以下的内容仅是提供参考,如果磁盘IO确实比较大 ...
- 利用windows的计划任务和eKing.CmdReadFileAndSendEmailOper(控制台小程序)实现远程登录服务器的邮件告警提醒
一.场景摘要: 1.windows计划任务中,有一个用户登录时候触发的事件 2.cmd命令:netstat -ano | find "3389" 可以看到当前远程登录的IP 3 ...