首先来看文件打包的工具类: import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.zip.Zip64Mode; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; public class ZipUtil { /** * zip压缩文件 * @param dir * @param zippath */ public static void zip(String dir ,String zippath){ List<String> paths = getFiles(dir); compressFilesZip(paths.toArray(new String[paths.size()]),zippath,dir ); } /** * 递归取到当前目录所有文件 * @param dir * @return */ public static List<String> getFiles(String dir){ List<String> lstFiles = null; if(lstFiles == null){ lstFiles = new ArrayList<String>(); } File file = new File(dir); File [] files = file.listFiles(); for(File f : files){ if(f.isDirectory()){ lstFiles.add(f.getAbsolutePath()); lstFiles.addAll(getFiles(f.getAbsolutePath())); }else{ String str =f.getAbsolutePath(); lstFiles.add(str); } } return lstFiles; } /** * 文件名处理 * @param dir * @param path * @return */ public static String getFilePathName(String dir,String path){ String p = path.replace(dir+File.separator, ""); p = p.replace("\\", "/"); return p; } /** * 把文件压缩成zip格式 * @param files 需要压缩的文件 * @param zipFilePath 压缩后的zip文件路径 ,如"D:/test/aa.zip"; */ public static void compressFilesZip(String[] files,String zipFilePath,String dir) { if(files == null || files.length <= 0) { return ; } ZipArchiveOutputStream zaos = null; try { File zipFile = new File(zipFilePath); zaos = new ZipArchiveOutputStream(zipFile); zaos.setUseZip64(Zip64Mode.AsNeeded); //将每个文件用ZipArchiveEntry封装 //再用ZipArchiveOutputStream写到压缩文件中 for(String strfile : files) { File file = new File(strfile); if(file != null) { String name = getFilePathName(dir,strfile); ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(file,name); zaos.putArchiveEntry(zipArchiveEntry); if(file.isDirectory()){ continue; } InputStream is = null; try { is = new BufferedInputStream(new FileInputStream(file)); byte[] buffer = new byte[1024 ]; int len = -1; while((len = is.read(buffer)) != -1) { //把缓冲区的字节写入到ZipArchiveEntry zaos.write(buffer, 0, len); } zaos.closeArchiveEntry(); }catch(Exception e) { throw new RuntimeException(e); }finally { if(is != null) is.close(); } } } zaos.finish(); }catch(Exception e){ throw new RuntimeException(e); }finally { try { if(zaos != null) { zaos.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } /** * 把zip文件解压到指定的文件夹 * @param zipFilePath zip文件路径, 如 "D:/test/aa.zip" * @param saveFileDir 解压后的文件存放路径, 如"D:/test/" () */ public static void unzip(String zipFilePath, String saveFileDir) { if(!saveFileDir.endsWith("\\") && !saveFileDir.endsWith("/") ){ saveFileDir += File.separator; } File dir = new File(saveFileDir); if(!dir.exists()){ dir.mkdirs(); } File file = new File(zipFilePath); if (file.exists()) { InputStream is = null; ZipArchiveInputStream zais = null; try { is = new FileInputStream(file); zais = new ZipArchiveInputStream(is); ArchiveEntry archiveEntry = null; while ((archiveEntry = zais.getNextEntry()) != null) { // 获取文件名 String entryFileName = archiveEntry.getName(); // 构造解压出来的文件存放路径 String entryFilePath = saveFileDir + entryFileName; OutputStream os = null; try { // 把解压出来的文件写到指定路径 File entryFile = new File(entryFilePath); if(entryFileName.endsWith("/")){ entryFile.mkdirs(); }else{ os = new BufferedOutputStream(new FileOutputStream( entryFile)); byte[] buffer = new byte[1024]; int len = -1; while((len = zais.read(buffer)) != -1) { os.write(buffer, 0, len); } } } catch (IOException e) { throw new IOException(e); } finally { if (os != null) { os.flush(); os.close(); } } } } catch (Exception e) { throw new RuntimeException(e); } finally { try { if (zais != null) { zais.close(); } if (is != null) { is.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } } /** * 把接受的全部文件打成压缩包 * @param List<File>; * @param org.apache.tools.zip.ZipOutputStream */ public static void zipFile(List files,ZipOutputStream outputStream) { int size = files.size(); for(int i = 0; i < size; i++) { File file = (File) files.get(i); zipFile(file, outputStream); } } public static void zipInputStreamFile(List<Map> files,ZipOutputStream outputStream) { if(files != null && files.size() > 0){ for(Map mm : files){ //获取文件输入流 InputStream inputStream = (InputStream) mm.get("inputStream"); String fileName= (String) mm.get("fileName"); zipFile(inputStream, fileName, outputStream); } } } /** * 根据输入的文件与输出流对文件进行打包 * @param File * @param org.apache.tools.zip.ZipOutputStream */ public static void zipFile(File inputFile, ZipOutputStream ouputStream) { try { if(inputFile.exists()) { /**如果是目录的话这里是不采取操作的, * 至于目录的打包正在研究中*/ if (inputFile.isFile()) { FileInputStream IN = new FileInputStream(inputFile); BufferedInputStream bins = new BufferedInputStream(IN, 512); //org.apache.tools.zip.ZipEntry ZipEntry entry = new ZipEntry(inputFile.getName()); ouputStream.putNextEntry(entry); // 向压缩文件中输出数据 int nNumber; byte[] buffer = new byte[512]; while ((nNumber = bins.read(buffer)) != -1) { ouputStream.write(buffer, 0, nNumber); } // 关闭创建的流对象 bins.close(); IN.close(); } else { try { File[] files = inputFile.listFiles(); for (int i = 0; i < files.length; i++) { zipFile(files[i], ouputStream); } } catch (Exception e) { e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } } public static void zipFile(InputStream IN,String fileName,ZipOutputStream ouputStream) { try { BufferedInputStream bins = new BufferedInputStream(IN, 512); //org.apache.tools.zip.ZipEntry ZipEntry entry = new ZipEntry(fileName); ouputStream.putNextEntry(entry); // 向压缩文件中输出数据 int nNumber; byte[] buffer = new byte[512]; while ((nNumber = bins.read(buffer)) != -1) { ouputStream.write(buffer, 0, nNumber); } // 关闭创建的流对象 bins.close(); IN.close(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { String unzipdir = "G:/Work/"; String unzipfile = "test.zip"; ZipUtil.unzip(unzipfile, unzipdir); System.out.println("success!"); } }
上面的工具类中我们主要用到了两个方法:
1.根据文件流的形式进行压缩:zipInputStreamFile(List<Map> files,ZipOutputStream outputStream)
files:参数代表待压缩的文件列表,每个Map属性应该包括,inputStream(文件流)和fileName属性(文件名称)
outputStream:压缩后的文件输出流
2.根据文件的 路径进行压缩:zipFile(List files,ZipOutputStream outputStream)
files:参数代表待压缩的文件列表,files为多个File文件对象
outputStream:压缩后的文件输出流
下面的例子是使用的zipInputStreamFile方法进行压缩下载的,第二种和第一种类似。
service实现类:
import java.io.File; import java.io.FileOutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.zip.ZipOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Service; import com.web.util.ZipUtil; @Service("testService") public class TestServiceImpl implements ITestService{ @Override public String getZipFilePath(HttpServletRequest request, HttpServletResponse response) { // TODO Auto-generated method stub //待压缩的文件列表 List<Map> files = new ArrayList<Map>(); try { //第一个文件远程地址 String file1Url = "http://bpic.588ku.com/element_origin_min_pic/16/06/24/03576c3b731eec6.jpg"; URL url1 = new URL(file1Url); HttpURLConnection connection1=(HttpURLConnection)url1.openConnection(); Map map1 = new HashMap(); map1.put("inputStream", connection1.getInputStream()); String file1Name = file1Url.substring(file1Url.lastIndexOf("/") + 1); map1.put("fileName", file1Name); files.add(map1); //第二个文件的远程地址 String file2Url = "http://bpic.588ku.com/element_origin_min_pic/16/09/20/1557e0e6f31cd58.jpg"; URL url2 = new URL(file2Url); HttpURLConnection connection2=(HttpURLConnection)url2.openConnection(); Map map2 = new HashMap(); map2.put("inputStream", connection2.getInputStream()); String file2Name = file2Url.substring(file2Url.lastIndexOf("/") + 1); map2.put("fileName", file2Name); files.add(map2); //第三个文件的远程地址 String file3Url = "http://bpic.588ku.com/element_origin_min_pic/02/13/31/01576a7c5a4262b.jpg"; URL url3 = new URL(file3Url); HttpURLConnection connection3=(HttpURLConnection)url3.openConnection(); Map map3 = new HashMap(); map3.put("inputStream", connection3.getInputStream()); String file3Name = file3Url.substring(file3Url.lastIndexOf("/") + 1); map3.put("fileName", file3Name); files.add(map3); //创建一个临时压缩文件,我们会把文件流全部注入到这个文件, 这里的文件你可以自定义是.rar还是.zip String picZipPath = "D://pic.zip"; File file = new File(picZipPath); //文件不存在创建文件 if (!file.exists()){ file.createNewFile(); } response.reset(); //创建文件输出流 FileOutputStream fous = new FileOutputStream (file); //打包的方法我们会用到ZipOutputStream这样一个输出流,所以这里我们把输出流转换一下 ZipOutputStream zipOut = new ZipOutputStream(fous); ZipUtil.zipInputStreamFile(files, zipOut); zipOut.close(); fous.close(); return picZipPath; } catch (Exception e) { // TODO: handle exception System.out.println("------"+e.getMessage()); } return ""; } }Controller层: import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping(value="/test") public class TestController { @Autowired private ITestService testService; @RequestMapping("download") public void testZipDownload(HttpServletRequest request,HttpServletResponse response){ try { //获取文件打包后的下载路径,业务自行处理 String zipFilePath = testService.getZipFilePath(request, response); response.setCharacterEncoding("utf-8"); response.setContentType("application/form-data");
//设置前端下载的文件名称 String fileName = new String("pic".getBytes("GB2312"), "ISO8859-1");response.setHeader("Content-Disposition", "attachment;fileName=" + fileName+".zip"); response.setBufferSize(1024); // 文件路径 File file = new File(zipFilePath); InputStream inputStream = new FileInputStream(file); OutputStream os = response.getOutputStream(); byte[] b = new byte[1024]; int length; while ((length = inputStream.read(b)) > 0) { os.write(b, 0, length); } inputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }
