java/resteasy批量下载存储在阿里云OSS上的文件,并打包压缩
现在需要从oss上面批量下载文件并压缩打包,搜了很多相关博客,均是缺胳膊少腿,要么是和官网说法不一,要么就压缩包工具类不给出
官方API https://help.aliyun.com/document_detail/32014.html?spm=a2c4g.11186623.6.683.txHAjx
我们采用流式下载,进行简单改装,可以从OSS取到多个文件
思路:ossClient.getObject()获取到文件
再用输入流获取ossObject.getObjectContent(),再利用输入流写入到字节流中,
关闭输入输出流,结束
读取文件接口:
/** * 根据订单编号查询多个大图路径 * 从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("文件打包成功"); }
写成流,设置response
下载文件接口:
/** * 流程 * 再将"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.java
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(); } } }
作者:Rest探路者
出处:http://www.cnblogs.com/Java-Starter/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意请保留此段声明,请在文章页面明显位置给出原文连接
Github:https://github.com/cjy513203427