返回 导航

其他

hangge.com

SpringBoot - 网络请求模版类RestTemplate使用详解5(下载文件)

作者:hangge | 2019-10-30 08:10

八、文件下载

1,简单的文件下载

(1)最简单的下载文件方式就是使用的是 restTemplate 调用 getForEntity 获取到字节数组,再将字节数组通过 java 8 Files 工具类的 write 方法,直接写到目标文件。
    该方式的缺点:由于需要将文件的字节数组全部放入内存中,极其消耗资源。当遇到大文件时,内存加载可能会造成 OutOfMemoryError

(2)下面是一个简单的样例,下载一个网络上的图片并保存到本地。
@RestController
public class HelloController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/test")
    public void test() {
        // 记录下开始下载时的时间
        Instant now = Instant.now();
        // 待下载的文件地址
        String url = "http://www.hangge.com/blog/images/logo.png";
        ResponseEntity<byte[]> rsp = restTemplate.getForEntity(url, byte[].class);
        System.out.println("状态码:" + rsp.getStatusCode());
        try {
            // 将下载下来的文件内容保存到本地
            String targetPath = "/Users/hangge/Desktop/logo.png";
            Files.write(Paths.get(targetPath), Objects.requireNonNull(rsp.getBody(),
                    "未获取到下载文件"));
        } catch (IOException e) {
            System.out.println("文件写入失败:" + e.getMessage());
        }
        System.out.println("文件下载完成,耗时:" + ChronoUnit.MILLIS.between(now, Instant.now())
                + " 毫秒");
        return;
    }
}

2,大文件的下载

    对于大文件的下载,建议使用流的方式来解决。即每次接收到一部分数据就直接写入到文件。这里我使用使用 Files copy 方法来处理流。
@RestController
public class HelloController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/test")
    public void test() {
        // 记录下开始下载时的时间
        Instant now = Instant.now();
        // 待下载的文件地址
        String url = "http://www.hangge.com/blog/images/logo.png";
        // 文件保存的本地路径
        String targetPath = "/Users/hangge/Desktop/logo.png";
        //定义请求头的接收类型
        RequestCallback requestCallback = request -> request.getHeaders()
                .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
        //对响应进行流式处理而不是将其全部加载到内存中
        restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {
            Files.copy(clientHttpResponse.getBody(), Paths.get(targetPath));
            return null;
        });
        System.out.println("文件下载完成,耗时:" + ChronoUnit.MILLIS.between(now, Instant.now())
                + " 毫秒");
        return;
    }
}
评论

全部评论(0)

回到顶部