如今須要從oss上面批量下載文件並壓縮打包,搜了不少相關博客,均是缺胳膊少腿,要麼是和官網說法不一,要麼就壓縮包工具類不給出html
官方API https://help.aliyun.com/document_detail/32014.html?spm=a2c4g.11186623.6.683.txHAjxjava
咱們採用流式下載,進行簡單改裝,能夠從OSS取到多個文件api
思路:ossClient.getObject()獲取到文件app
再用輸入流獲取ossObject.getObjectContent(),再利用輸入流寫入到字節流中,工具
關閉輸入輸出流,結束ui
讀取文件接口:spa
/** * 根據訂單編號查詢多個大圖路徑 * 從OSS取出來多個文件 * 在"D:\\download"進行讀取 * 在"D:\\downloadZip"進行壓縮 * @param orderNumber * @return * @throws Exception */ @GET @Path("readOssFile") @Produces(MediaType.APPLICATION_JSON) public PcsResult readOssFile(@QueryParam("orderNumber") String orderNumber) throws Exception { //orderNumber = 194785 if(orderNumber==null){ logger.error("訂單編號不能爲空!"); throw new Exception("訂單編號不能爲空!"); } List<Map<String,String>> imagePath = myOrderService.queryImageByOrderNumber(orderNumber); List<String> objectNames = new ArrayList<>(); for (Map<String,String> image:imagePath){ objectNames.add(image.get("imagePath")); } // 建立OSSClient實例。 OSSClient ossClient = new OSSClient(END_POINT, ACCESSKEY_ID, ACCESSKEY_SECRET); //ossObject包含文件所在的存儲空間名稱、文件名稱、文件元信息以及一個輸入流。 /* 多文件,循環遍歷ossClient的Object */ for(int i=0;i<objectNames.size();i++) { OSSObject ossObject = ossClient.getObject(BUCKET_NAME, objectNames.get(i)); File fileDir = new File(fileDirectory); FileToolUtil.judeDirExists(fileDir); // 讀取文件內容。 // file(內存)----輸入流---->【程序】----輸出流---->file(內存) File file = new File(fileDirectory, "addfile"+i+".png"); BufferedInputStream in=null; BufferedOutputStream out=null; in=new BufferedInputStream(ossObject.getObjectContent()); out=new BufferedOutputStream(new FileOutputStream(file)); int len=-1; byte[] b=new byte[1024]; while((len=in.read(b))!=-1){ out.write(b,0,len); } //關閉輸入輸出流 IOUtils.closeQuietly(out); IOUtils.closeQuietly(in); } //新建文件夾以備壓縮文件存放 File fileDir1 = new File(fileDirectory1); FileToolUtil.judeDirExists(fileDir1); //執行壓縮操做 ZipUtils.doCompress(fileDirectory, fileDirectory1+"\\" + orderNumber + ".zip"); //數據讀取完成後,獲取的流必須關閉,不然會形成鏈接泄漏,致使請求無鏈接可用,程序沒法正常工做。 ossClient.shutdown(); return newResult(true).setMessage("文件打包成功"); }
寫成流,設置responsecode
下載文件接口:htm
/** * 流程 * 再將"D:\\download"文件夾刪除 * 再將"D:\\download"文件夾刪除 * @return * @throws IOException */ @GET @Path("getOssFile") @Produces(MediaType.APPLICATION_JSON) public void getOssFile(@QueryParam("orderNumber") String orderNumber,@Context HttpServletResponse response) throws Exception { //根據存放在fileDirectory1下的壓縮文件生成下載請求 OutputStream out = null; FileInputStream in = null; try { in = new FileInputStream(fileDirectory1+"\\" + orderNumber + ".zip"); String fileName = orderNumber + ".zip"; //設置文件輸出類型 response.setContentType("application/octet-stream"); response.setHeader("Content-disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1")); byte[] data = FileToolUtil.inputStreamToByte(in); //設置輸出長度 response.setHeader("Content-Length", String.valueOf(data.length)); out = response.getOutputStream(); out.write(data); out.flush(); //數據讀取完成後,獲取的流必須關閉,不然會形成鏈接泄漏,致使請求無鏈接可用,程序沒法正常工做。 }catch (Exception e){ logger.error(".....getOssFile....", e); }finally { IOUtils.closeQuietly(out); IOUtils.closeQuietly(in); DeleteFileUtil.delete(fileDirectory); DeleteFileUtil.delete(fileDirectory1); } }
補充:ZipUtil.javablog
package com.xgt.util; import java.io.*; import java.util.zip.CRC32; import java.util.zip.CheckedOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** * ZIP壓縮工具 * * @since 1.0 */ public class ZipUtils { public static final String EXT = ".zip"; private static final String BASE_DIR = ""; // 符號"/"用來做爲目錄標識判斷符 private static final String PATH = "/"; private static final int BUFFER = 1024; /** * 壓縮 * * @param srcFile * @throws Exception */ public static void compress(File srcFile) throws Exception { String name = srcFile.getName(); String basePath = srcFile.getParent(); String destPath = basePath + name + EXT; compress(srcFile, destPath); } /** * 壓縮 * * @param srcFile 源路徑 * @param destFile 目標路徑 * @throws Exception */ public static void compress(File srcFile, File destFile) throws Exception { // 對輸出文件作CRC32校驗 CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream( destFile), new CRC32()); ZipOutputStream zos = new ZipOutputStream(cos); compress(srcFile, zos, BASE_DIR); zos.flush(); zos.close(); } /** * 壓縮文件 * * @param srcFile * @param destPath * @throws Exception */ public static void compress(File srcFile, String destPath) throws Exception { compress(srcFile, new File(destPath)); } /** * 壓縮 * * @param srcFile 源路徑 * @param zos ZipOutputStream * @param basePath 壓縮包內相對路徑 * @throws Exception */ private static void compress(File srcFile, ZipOutputStream zos, String basePath) throws Exception { if (srcFile.isDirectory()) { compressDir(srcFile, zos, basePath); } else { compressFile(srcFile, zos, basePath); } } /** * 壓縮 * * @param srcPath * @throws Exception */ public static void compress(String srcPath) throws Exception { File srcFile = new File(srcPath); compress(srcFile); } /** * 文件壓縮 * * @param srcPath 源文件路徑 * @param destPath 目標文件路徑 */ public static void compress(String srcPath, String destPath) throws Exception { File srcFile = new File(srcPath); compress(srcFile, destPath); } /** * 壓縮目錄 * * @param dir * @param zos * @param basePath * @throws Exception */ private static void compressDir(File dir, ZipOutputStream zos, String basePath) throws Exception { File[] files = dir.listFiles(); // 構建空目錄 if (files.length < 1) { ZipEntry entry = new ZipEntry(basePath + dir.getName() + PATH); zos.putNextEntry(entry); zos.closeEntry(); } for (File file : files) { // 遞歸壓縮 compress(file, zos, basePath + dir.getName() + PATH); } } /** * 文件壓縮 * * @param file 待壓縮文件 * @param zos ZipOutputStream * @param dir 壓縮文件中的當前路徑 * @throws Exception */ private static void compressFile(File file, ZipOutputStream zos, String dir) throws Exception { /** * 壓縮包內文件名定義 * * <pre> * 若是有多級目錄,那麼這裏就須要給出包含目錄的文件名 * 若是用WinRAR打開壓縮包,中文名將顯示爲亂碼 * </pre> */ ZipEntry entry = new ZipEntry(dir + file.getName()); zos.putNextEntry(entry); BufferedInputStream bis = new BufferedInputStream(new FileInputStream( file)); int count; byte data[] = new byte[BUFFER]; while ((count = bis.read(data, 0, BUFFER)) != -1) { zos.write(data, 0, count); } bis.close(); zos.closeEntry(); } public static void doCompress(String srcFile, String zipFile) throws IOException { doCompress(new File(srcFile), new File(zipFile)); } /** * 文件壓縮 * @param srcFile 目錄或者單個文件 * @param zipFile 壓縮後的ZIP文件 */ public static void doCompress(File srcFile, File zipFile) throws IOException { ZipOutputStream out = null; try { out = new ZipOutputStream(new FileOutputStream(zipFile)); doCompress(srcFile, out); } catch (Exception e) { throw e; } finally { out.close();//記得關閉資源 } } public static void doCompress(String filelName, ZipOutputStream out) throws IOException{ doCompress(new File(filelName), out); } public static void doCompress(File file, ZipOutputStream out) throws IOException{ doCompress(file, out, ""); } public static void doCompress(File inFile, ZipOutputStream out, String dir) throws IOException { if ( inFile.isDirectory() ) { File[] files = inFile.listFiles(); if (files!=null && files.length>0) { for (File file : files) { String name = inFile.getName(); if (!"".equals(dir)) { name = dir + "/" + name; } ZipUtils.doCompress(file, out, name); } } } else { ZipUtils.doZip(inFile, out, dir); } } public static void doZip(File inFile, ZipOutputStream out, String dir) throws IOException { String entryName = null; if (!"".equals(dir)) { entryName = dir + "/" + inFile.getName(); } else { entryName = inFile.getName(); } ZipEntry entry = new ZipEntry(entryName); out.putNextEntry(entry); int len = 0 ; byte[] buffer = new byte[1024]; FileInputStream fis = new FileInputStream(inFile); while ((len = fis.read(buffer)) > 0) { out.write(buffer, 0, len); out.flush(); } out.closeEntry(); fis.close(); } public static void main(String[] args) throws IOException { doCompress("E:\\py交易\\download", "E:\\py交易\\download\\效果圖批量下載.zip"); } }
FileToolUtil.java
package com.xgt.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; public class FileToolUtil { private static final Logger logger = LoggerFactory.getLogger(FileToolUtil.class); /** * @author cjy * @date 2018/6/5 14:35 * @param file * @return */ // 判斷文件夾是否存在 public static void judeDirExists(File file) { if (file.exists()) { if (file.isDirectory()) { System.out.println("dir exists"); } else { System.out.println("the same name file exists, can not create dir"); } } else { System.out.println("dir not exists, create it ..."); file.mkdir(); } } }