Java 下载多个文件打成zip压缩包

Java 下载多个文件打成zip压缩包

准备:

  1. 单个文件下载接口
  2. 文件下载地址
  3. RestTemplate运用

思路:

  1. 文件下载是文件读入与输出(字节流)的过程。
  2. 调用rpc接口,获取多个文件字节流
  3. 创建一个zip文件输出流,将多个文件字节流输出到zip,生成一个临时zip文件
  4. 创建新的输入流读zip文件字节,将字节流输出。(文件下载)
  5. 删除zip临时文件,并关闭流

需求场景:

  1. 下载勾选的多个文件,打成一个zip包,下载。 下载的文件可以通过rpc或者本地文件下载。

说明:

  1. 通过现有接口,下载文件在打成zip包,或者自己读文件打成zip包,思路是一样的。

1.demo

FileController.class

@RestController
@RequestMapping("/file")
public class FileController {
    @Resource
    private IFileService fileService;

    @GetMapping("/indirectDown")
    public void indirectDownFile(@RequestParam("fileId") String fileId,HttpServletResponse response) throws IOException {
        fileService.indirectDownFile(fileId,response);
    }

    @GetMapping("/directDown")
    public void directDownFile(@RequestParam("fileIds") List<String> fileIds, HttpServletResponse response) throws IOException {
        fileService.directDownFile(fileIds,response);
    }

}

IFileService.class

public interface IFileService {

    void indirectDownFile(String fileId,HttpServletResponse response) throws IOException;

    void directDownFile(List<String> fileIds, HttpServletResponse response) throws IOException;
}

IFileService.class

@Service
public class IFileServiceImpl implements IFileService {
    @Resource
    private RestTemplate restTemplate;
    @Value("${tmpFilePath}")
    private String tmpFilePath;
    @Override
    public void indirectDownFile(String fileId,HttpServletResponse response) throws IOException {
        File file = new File("C:\\Users\\Administrator\\Pictures\\Saved Pictures\\壁纸\\"+fileId+".jpg");
        InputStream is = new FileInputStream(file);
        byte[] bs = new byte[1024];
        int len = -1;

        ServletOutputStream outputStream = response.getOutputStream();

        response.setContentType("application/msexcel;charset=utf-8");//定义输出类型
        response.setHeader("Content-Disposition","attachment;fileName=" +fileId+ ".jpg");

        while((len = is.read(bs)) != -1){
            outputStream.write(bs,0, len);
            outputStream.flush();
        }


    }

    @Override
    public void directDownFile(List<String> fileIds, HttpServletResponse response) throws IOException {

        // 1.设置相应头,下载所有需要的文件,获取byte字节流,获取输出流对象
        response.setContentType("application/msexcel;charset=utf-8");//定义输出类型
        response.setHeader("Content-Disposition","attachment;fileName=1.zip");
        ServletOutputStream os = response.getOutputStream();
        List<byte[]> ret = downloadFiles(fileIds);

        // 2.封装zip压缩包,需要先创建文件夹
        File file = new File(tmpFilePath);
        if(!file.isDirectory()){
            file.mkdirs();
        }

        ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(tmpFilePath+File.separator+"1.zip"));
        InputStream is = new FileInputStream(tmpFilePath+File.separator+"1.zip");
        for (byte[] bytes : ret) {
            String fileName = UUID.randomUUID().toString();

            zipOut.putNextEntry(new ZipEntry(fileName+".jpg"));
            zipOut.write(bytes,0,bytes.length);
            zipOut.flush();
        }
        zipOut.close();


        //3.将zip输出
        byte[] zipBytes = new byte[1024];
        int len = -1;
        while((len = is.read(zipBytes)) != -1){
            os.write(zipBytes,0,len);

        }
        os.flush();
        os.close();
        is.close();

        //4.删除生成的临时zip
        File tmpZip = new File(tmpFilePath+File.separator+"1.zip");
        tmpZip.delete();

    }

    private List<byte[]> downloadFiles(List<String> fileIds) {
        List<byte[]> ret = new ArrayList<>();
        fileIds.stream().forEach(fileId->{
            String url = "http://localhost:8081/file/indirectDown?fileId="+fileId;
            byte[] bs = restTemplate.getForObject(url, byte[].class);
            ret.add(bs);
        });
        return ret;
    }
}

SpringBoot启动类:RestDownloadApp

主要是注册一个RestTemplate bean,没有其它特殊需要说明的。

@SpringBootApplication
public class RestDownloadApp {

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(RestDownloadApp.class,args);
    }
}

application.yml

配置文件中的内容根据需要进行修改。如果端口号变了,记得要在IFileServiceImpl中修改Rpc 接口的地址。端口修改一致就行。

server:
  port: 8081
#文件下载 暂存目录
tmpFilePath: E:\\tmpFile

2.说明

如果是本地服务文件下载就可以省略rpc获取文件流的哪一步了。直接读取本地文件流。构建ZipEntry对象。赋值到zip输出流中。

其它部分不需要改变。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐