Spring boot 文件下载 文件压缩

2018-10-22  本文已影响0人  金刚_30bf

文件下载

代码:

    @GetMapping("/download")
    public ResponseEntity<FileSystemResource> downloadFile(HttpServletRequest request) {

        // 获取上送参数 
        String currentPath  = request.getParameter("currentPath");
        String subPath  = request.getParameter("subPath");
        String fileName  = request.getParameter("fileName");
        String download  = request.getParameter("download");
        
        String dpath = "";
        String dname = "";
        boolean isfail = false;
        String msg = "";
        
        log.debug("下载文件请求参数: " + currentPath + " " + subPath + " " + fileName + " " + download);
        
        // 下载目录时, 检查  download 为1  , 压缩目录 root + currentPath + subPath 
        if (StringUtils.equals(download, "1")) {
            String tmppath  = FileUtil.contactPath(currentPath, subPath);
            String dirpath = FileUtil.contactPath(this.fileRoot, tmppath);
            String zipname = ".zip";
            
            if (StringUtils.isBlank(tmppath) || StringUtils.equals(tmppath, File.separator)) {
                // 当tmppath 为空时, 取名为 root 
                zipname = "root" + zipname;
            } else {
                String[] strs = tmppath.split(Matcher.quoteReplacement(File.separator));
                zipname = strs[strs.length - 1] + zipname;
            }
            
            // zip 文件保存路径 
            // 使用随机字符串生成路径
            String zippath = FileUtil.contactPath(this.download_root, UUID.randomUUID().toString());
            
            log.debug("开始压缩文件: " + dirpath + " " + zippath + " " + zipname);
            
            try {
                FileUtil.folder2zip(dirpath, zippath, zipname);
            } catch (Exception exp) {
                log.error("压缩文件出现异常 :" ,exp);
                isfail = true;
                msg = "压缩文件异常:" + exp.getMessage();
            }
            
            dpath = FileUtil.contactPath(zippath, zipname);
            dname = zipname;
            
        } else {
            // 下载文件时, 检查  fileName不空 , 路径为 root + currentPath + fileName 
            
            if (StringUtils.isBlank(fileName)) {
                log.debug("下载文件时, 上送文件名称为空!");
                isfail = true;
                msg ="下载文件时, 上送文件名称为空!";
            } else {
                dpath  = FileUtil.contactPath(this.fileRoot, FileUtil.contactPath(currentPath,  fileName));
                dname = fileName;
            }
        }
        
        log.info("下载文件路径及名称:" + dpath + " " + dname);
        
        if (isfail) {
            log.info("下载失败" + msg);
            return null;
        } 
        
        return this.export(new File(dpath));
        /**
        else {
            response.setContentType("application/force-download");// 设置强制下载不打开
            response.addHeader("Content-Disposition", "attachment;fileName=" + dname);// 设置文件名
            
            File file = new File(dpath);
            
            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                OutputStream os = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = bis.read(buffer);
                }
                os.close();
                return  ;
            } catch (Exception e) {
                log.error("读取下载文件异常!" , e);
                
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        log.error("" , e);
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        log.error("" , e);
                        e.printStackTrace();
                    }
                }
            }
        }
        **/
    }
    
    public ResponseEntity<FileSystemResource> export(File file) {
        if (file == null) {
            return null;
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        return ResponseEntity
                .ok()
                .headers(headers)
                .contentLength(file.length())
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(new FileSystemResource(file));
    }

下载使用的是 ResponseEntity<FileSystemResource> , 若使用方法中注释的部分, 直接写response, 可能会报异常 : 写流已打开.

UT010006: Cannot call getWriter(), getOutputStream() already called

文件夹压缩

代码:

    /**
     * 压缩当前目录path下的所有文件 , 生成文件名称为 zipname , 放在路径zippath下 ; 
     * 有异常则抛出 ;
     * @param path
     * @param zippath
     * @param zipname
     * @throws IOException 
     */
    public static void folder2zip(String path, String zippath, String zipname) {
        File src = new File(path);
        ZipOutputStream zos = null;
        
        
        if (src == null  || !src.exists() || !src.isDirectory()) {
            // 源目录不存在 或不是目录 , 则异常  
            logger.error("压缩源目录不存在或非目录!" + path);
            throw new RuntimeException("压缩源目录不存在或非目录!" + path);
        }
        
        File destdir = new File(zippath);
        
        if (!destdir.exists()) {
            // 创建目录  
            logger.info("压缩目标路径不存在, 创建之." + zippath);
            destdir.mkdirs();
        }
        
        File zipfile = new File(contactPath(zippath, zipname));
        
        
        File[] srclist = src.listFiles();
        
        if (srclist == null || srclist.length == 0) {
            // 源目录内容为空,无需压缩 
            logger.error("源目录内容为空,无需压缩下载!" + path);
            throw new RuntimeException("源目录内容为空,无需压缩下载!" + path);
        }
        
        try {
            zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipfile)));
            
            // 递归压缩目录下所有的文件  ;
            compress(zos, src, src.getName());
            
            zos.close();
            
        } catch (FileNotFoundException e) {
            logger.error("压缩文件不存在", e);
            throw new RuntimeException("压缩目标文件不存在!" + e.getMessage());
        } catch (IOException e) {
            logger.error("压缩文件IO异常", e);
            throw new RuntimeException("压缩文件IO异常!" + e.getMessage());
        } 
        finally {
            if (zos != null) {
                try {
                    zos.close();
                } catch (Exception e2) {
                    // TODO: handle exception
                }
            }
        }
        
    }
    
    /**
     * 递归压缩文件 
     * @param zos
     * @param src
     * @throws IOException 
     */
    private static void compress(ZipOutputStream zos, File src, String name) throws IOException {
        if (src == null || !src.exists()) {
            return ;
        } 
        if (src.isFile()) {
            byte[] bufs = new byte[10240];
            
            ZipEntry zentry = new ZipEntry(name);
            zos.putNextEntry(zentry);
            
            logger.debug("压缩:" + src.getAbsolutePath());
            FileInputStream in = new FileInputStream(src);
            
            BufferedInputStream bin = new BufferedInputStream(in, 10240);
            
            int readcount = 0 ; 
            
            while( (readcount = bin.read(bufs, 0 , 10240)) != -1) {
                zos.write(bufs, 0 , readcount);
            }
            
            zos.closeEntry();
            bin.close();
        } else {
            // 文件夹  
            File[] fs = src.listFiles();
            
            if (fs == null || fs.length == 0 ) {
                zos.putNextEntry(new ZipEntry(name + File.separator ));
                zos.closeEntry();
                return ;
            }
            
            for (File f : fs) {
                compress(zos, f, name + File.separator + f.getName());
            }
        }
    }

注意: 如何保留原压缩目录的结构 .

上一篇下一篇

猜你喜欢

热点阅读