您的位置:首页 > 编程语言 > Java开发

【Java】Java实现批量打包文件Zip下载

2017-05-19 16:18 1156 查看
有这样一个需求,需要将某个文件夹进行下载,而且该文件下包含多张图片,图片是存储于Linux服务器上的。故采用zip打包方式进行下载。在此并没有采用获取网络图片的方式进行下载,而是找到图片在服务器上存储路径进行打包下载。废话不多说,直接上代码吧!!

1、页面功能如下图:



2、JS代码如下:

/**
* 点击下载当前文件夹
*
*/

function downloadFileImage(i){

var fileTid = $(i).attr("fileTid");
var fileName = $(i).attr("fileName");
$.ajax({
url:'../../file/tofindImagesFiles.do',
type : "post",
dataType:'json',
async : false,
data:{tid:fileTid},
success:function(data){
if(data.result=='no'){
alert('该文件夹下没有图片信息');
}else{
window.location.href='../../file/downLoadZipFile.do?tid='+fileTid+'&fileName='+fileName;
}
}
});

}3、Controller方法代码如下:
/**
* 单个文件打包(包含文件下的图片)下载
* @param request
* @param response
* @param model
* @param tid
* @return
* @author zhangsq
*/
@RequestMapping(value = "/downLoadZipFile.do")
public @ResponseBody Map<String, Object> toHmFileSaveAs(HttpServletRequest request, HttpServletResponse response,
ModelMap model,String tid) throws IOException {
Map<String, Object> map = new HashMap<String, Object>();
// 获取项目webapp目录路径下的文件
//String path = request.getSession().getServletContext().getRealPath("/");
String path = properties.getProperty("file.acpath.server");
//根据Tid获取文件信息
HmFile files = hmFileService.findByTidFilesInfo(tid);

String zipName = files.getFileName().concat(".zip");
ZipOutputStream outputStream = new ZipOutputStream(response.getOutputStream());

//根据tid=hid获取图片信息
List<HmImage> imgList = hmImagesService.findByHidImageShow(files.getTid());
if(imgList != null && imgList.size()>0){
try {
for(Iterator<HmImage> iterator = imgList.iterator();iterator.hasNext();){
response.setContentType("APPLICATION/OCTET-STREAM");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipName, "UTF-8"));
HmImage img = iterator.next();
String filePath = img.getFilePath().substring(0,img.getFilePath().indexOf("?"));
String realname = filePath.substring(filePath.lastIndexOf("/")+1);
String filedir =File.separator+ files.getFileSpell();
String filelocationdir = path + filedir + File.separator + realname;
ZipUtils.doCompress(filelocationdir, outputStream);
response.flushBuffer();
}
} catch (Exception e) {
e.printStackTrace();
ServletOutputStream sos = null;
try {
response.setContentType("text/html;charset=utf-8");
sos = response.getOutputStream();
sos.write("<script>alert('下载失败,请与管理员联系~~');</script>".getBytes());
sos.flush();
} catch (IOException e1) {
e1.printStackTrace();
}finally{
if(null != sos){
try {
sos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}finally{
outputStream.close();
}

}else{
ZipUtils.doCompress(files.getFileName(), outputStream);
response.flushBuffer();
outputStream.close();
}
map.put("success",true);
return map;
}其中:
file.acpath.server为配置文件中配置的服务器路径。



String zipName = files.getFileName().concat(".zip");为文件打包时候的包名。

doCompress为公共工具类ZipUtils中的方法。

3、公共工具类ZipUtils全部代码如下:

package com.zxct.edu.utils;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

/**
* 压缩文件工具类
*
* @author zhangsq 2017年4月10日 v1.0
*/
public class ZipUtils {

public static void doCompress(String srcFile, String zipFile) throws Exception {
doCompress(new File(srcFile), new File(zipFile));
}

/**
* 文件压缩
*
* @param srcFile
* 目录或者单个文件
* @param destFile
* 压缩后的ZIP文件
*/
public static void doCompress(File srcFile, File destFile) throws Exception {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(destFile));
if (srcFile.isDirectory()) {
File[] files = srcFile.listFiles();
for (File file : files) {
doCompress(file, out);
}
} else {
doCompress(srcFile, out);
}
}

public static void doCompress(String pathname, ZipOutputStream out) throws IOException {
doCompress(new File(pathname), out);
}

public static void doCompress(File file, ZipOutputStream out) throws IOException {
if (!file.exists()) {
return;
}
byte[] buffer = new byte[1024];
FileInputStream fis = new FileInputStream(file);
out.putNextEntry(new ZipEntry(file.getName()));
int len = 0;
// 读取文件的内容,打包到zip文件
while ((len = fis.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.flush();
out.closeEntry();
fis.close();
}

/**
* 压缩文件列表中的文件
*
* @param files
* @param outputStream
* @throws IOException
*/
public static void zipFile(List files, ZipOutputStream outputStream) throws IOException, ServletException {
try {
int size = files.size();
// 压缩列表中的文件
for (int i = 0; i < size; i++) {
File file = (File) files.get(i);
zipFile(file, outputStream);
}
} catch (IOException e) {
throw e;
}
}

/**
* 将文件写入到zip文件中
*
* @param inputFile
* @param outputstream
* @throws Exception
*/
public static void zipFile(File inputFile, ZipOutputStream outputstream) throws IOException, ServletException {
try {
if (inputFile.exists()) {
if (inputFile.isFile()) {
FileInputStream inStream = new FileInputStream(inputFile);
BufferedInputStream bInStream = new BufferedInputStream(inStream);
ZipEntry entry = new ZipEntry(inputFile.getName());
outputstream.putNextEntry(entry);

final int MAX_BYTE = 10 * 1024 * 1024; // 最大的流为10M
long streamTotal = 0; // 接受流的容量
int streamNum = 0; // 流需要分开的数量
int leaveByte = 0; // 文件剩下的字符数
byte[] inOutbyte; // byte数组接受文件的数据

streamTotal = bInStream.available(); // 通过available方法取得流的最大字符数
streamNum = (int) Math.floor(streamTotal / MAX_BYTE); // 取得流文件需要分开的数量
leaveByte = (int) streamTotal % MAX_BYTE; // 分开文件之后,剩余的数量

if (streamNum > 0) {
for (int j = 0; j < streamNum; ++j) {
inOutbyte = new byte[MAX_BYTE];
// 读入流,保存在byte数组
bInStream.read(inOutbyte, 0, MAX_BYTE);
outputstream.write(inOutbyte, 0, MAX_BYTE); // 写出流
}
}
// 写出剩下的流数据
inOutbyte = new byte[leaveByte];
bInStream.read(inOutbyte, 0, leaveByte);
outputstream.write(inOutbyte);
outputstream.closeEntry();
bInStream.close(); // 关闭
inStream.close();
}
} else {
throw new ServletException("文件不存在!");
}
} catch (IOException e) {
throw e;
}
}

}这样就可以了,在浏览器端点击下载,如下图:



找到下载的文件夹,并解压:



打开解压后文件,就看到下载成功了。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: