基于OKHttp的大文件下载

1.需求:

根据Url下载大文件,本地创建文件,从输入流读取并写入文件,要求能满足大文件的下载,不能出现OOM

2.引入依赖
xml 复制代码
<!-- OK HTTP -->
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.12.0</version>
</dependency>
<!-- Hutool工具包 -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.16</version>
</dependency>
3.下载文件代码
java 复制代码
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.net.URLDecoder;
import java.nio.charset.StandardCharsets;


/**
 * 下载文件并保存
 * @param url 下载地址
 * @param folder 本地保存文件夹路径,比如:E:\test\down
 * @return 文件(下载失败返回null)
 */
public File downloadFile(String url, String folder){
    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder().url(url).build();

    try(Response response = client.newCall(request).execute()){
        if(response.isSuccessful()){
            if(Objects.isNull(response.body())){
                logger.info("下载失败,响应体为空");
                return null;
            }
            //从Url提取文件名
            String fileName = getFileNameFromUrl(url);
     
            //拼接完整文件路径
            String filePath = folder + File.separator + fileName;
            //创建本地文件
            File file = new File(filePath);
            FileUtil.touch(file);
            try(
                InputStream in = response.body().byteStream();//获取响应输入流
                FileOutputStream out = new FileOutputStream(file)//创建文件输出流
            ){
                //写入本地文件
                int len;
                byte[] buffer = new byte[4096];
                while((len = in.read(buffer)) != -1) { //从输入流中读取数据到缓冲区
                    out.write(buffer, 0, len); //将缓冲区的数据写入输出流
                }
                out.flush(); //刷新输出流缓冲区
            }
            return file;
        }else{
            logger.info("响应失败:httpStatus={}", response.code());
            return null;
        }
    }catch (Exception e){
        logger.info("文件下载失败,地址:{},错误:{}", url, e.getMessage(), e);
        return null;
    }
}

/**
 * 从Url提取文件名
 * @param url 文件路径
 * @return 文件名
 */
private static String getFileNameFromUrl(String url){
    String uri = URLDecoder.decode(url.trim(), StandardCharsets.UTF_8);
    int index = uri.lastIndexOf("/");
    return  index==-1 ? uri : uri.substring(index+1);
}
相关推荐
头发还在的女程序员5 小时前
医院陪诊管理系统怎么选择?——2026 年选型避坑与架构参考
java·开发语言·陪诊系统·陪诊app·医院陪诊陪护
CodeStats6 小时前
【Spring事务】Spring事务注解 @Transactional 完整体系:从 MySQL 隔离级别到 MyBatis 原理详解
java·spring·mybatis·事务·transactional
我命由我123456 小时前
Android 开发问题:为 PDFView 设置一个带有黑色边框的背景 drawable,但边框没有生效
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
都叫我大帅哥8 小时前
从Python到Java:为什么企业级Agent最终会选择Java?
java·ai编程
wanderist.9 小时前
Lambda表达式在算法竞赛中的应用
java·开发语言·算法
腻害兔10 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:IM 即时通讯模块,一个被低估的「全功能聊天系统」
java·前端·vue.js·产品经理·ai编程
心念枕惊10 小时前
.NET CORE 授权进阶-角色、策略与动态权限实现
java·前端·.netcore
景同学12 小时前
把 AI 用到线上运维:可行、有效,前提是喂足信息——一次 Full GC 排障实录
java·人工智能·后端
C++、Java和Python的菜鸟12 小时前
第7章 后端Web实战(Tlias系统)
java
憧憬成为java架构高手的小白13 小时前
黑马八股--spring框架学习
java·学习·spring