java實現文件打包壓縮下載接口(附上可實際運行的代碼)

最近在寫項目接口,涉及到文件下載、打包壓縮下載,單個文件下載還是比較簡單的,多文件下載涉及到打包和壓縮知識,之前也沒做過,寫篇博客做個簡單的記錄一下。閒言少敘,上代碼:

如下代碼是精簡過後的測試代碼,親測可實際使用:

/**
 * @author simons.fan
 * @version 1.0
 * @date 2019/7/9
 * @description 文件下載controller
 **/
@RestController
@RequestMapping("/file")
public class FileController {
 
    private static final Logger logger = LoggerFactory.getLogger(FileController.class);
 
    @Autowired
    private DownLoadService downLoadService;
 
    /**
     * 單個文件下載
     *
     * @param fileName 真實存在的文件名
     */
    @GetMapping("/down-one")
    public void downOneFile(@RequestParam(value = "filename", required = false) String fileName) {
        logger.info("單個文件下載接口入參:[filename={}]", fileName);
        if (fileName.isEmpty()) {
            return;
        }
        try {
            downLoadService.downOneFile(fileName);
        } catch (Exception e) {
            logger.error("單個文件下載接口異常:{fileName={},ex={}}", fileName, e);
        }
    }
 
    /**
     * 批量打包下載文件
     *
     * @param fileName 文件名,多個用英文逗號分隔
     */
    @GetMapping("/down-together")
    public void downTogether(@RequestParam(value = "filename", required = false) String fileName) {
        logger.info("批量打包文件下載接口入參:[filename={}]", fileName);
        if (fileName.isEmpty()) return;
        List<String> fileNameList = Arrays.asList(fileName.split(","));
        if (CollectionUtils.isEmpty(fileNameList)) return;
        try {
            downLoadService.downTogetherAndZip(fileNameList);
        } catch (Exception e) {
            logger.error("批量打包文件下載接口異常:{fileName={},ex={}}", fileName, e);
        }
    }
}
/**
 * @author simons.fan
 * @version 1.0
 * @date 2019/7/9
 * @description 文件下載service
 **/
@Service
public class DownLoadServiceImpl implements DownLoadService {
 
    private static final Logger logger = LoggerFactory.getLogger(DownLoadServiceImpl.class);
 
    @Value("${file.path}")
    private String FILE_ROOT_PATH;
 
    /**
     * 單個文件下載
     *
     * @param fileName 單個文件名
     * @throws Exception
     */
    @Override
    public void downOneFile(String fileName) throws Exception {
        HttpServletResponse resp = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        File file = new File(FILE_ROOT_PATH + fileName);
        if (file.exists()) {
            resp.setContentType("application/x-msdownload");
            resp.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(), "ISO-8859-1"));
            InputStream inputStream = new FileInputStream(file);
            ServletOutputStream ouputStream = resp.getOutputStream();
            byte b[] = new byte[1024];
            int n;
            while ((n = inputStream.read(b)) != -1) {
                ouputStream.write(b, 0, n);
            }
            ouputStream.close();
            inputStream.close();
        }
    }
 
    /**
     * 文件批量打包下載
     *
     * @param fileNameList 多個文件名,用英文逗號分隔開
     * @throws IOException
     */
    @Override
    public void downTogetherAndZip(List<String> fileNameList) throws IOException {
        HttpServletResponse resp = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        resp.setContentType("application/x-msdownload");
        //暫時設定壓縮下載後的文件名字爲test.zip
        resp.setHeader("Content-Disposition", "attachment;filename=test.zip");
        String str = "";
        String rt = "\r\n";
        ZipOutputStream zos = new ZipOutputStream(resp.getOutputStream());
        for (String filename : fileNameList) {
            str += filename + rt;
            File file = new File(FILE_ROOT_PATH + filename);
            zos.putNextEntry(new ZipEntry(filename));
            FileInputStream fis = new FileInputStream(file);
            byte b[] = new byte[1024];
            int n = 0;
            while ((n = fis.read(b)) != -1) {
                zos.write(b, 0, n);
            }
            zos.flush();
            fis.close();
        }
        //設置解壓文件後的註釋內容
        zos.setComment("download success:" + rt + str);
        zos.flush();
        zos.close();
    }
}

跑起來,測試,ok~

題外話

我們項目使用的是阿里雲的OSS文件服務器,用過的小夥伴會發現,從OSS服務器返回的的是一個"OSSObject"對象,通過OSSObject對象,只能拿到對應的InputStream流,當時剛開始做,想法是直接將這個InputStream流寫入到ZipOutputStream,一直不行。折騰半天,決定將這個InputStream流臨時寫入到運行服務的linux服務器,再來讀這個file,當把這個文件寫入到壓縮對象類ZipOutputStream後,直接刪除這個file即可,順利解決我的問題。

發佈了35 篇原創文章 · 獲贊 11 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章