尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
为什么你的断点续传总是从 0 开始:Hutool 大文件下载避坑实战
为什么你的断点续传总是从 0 开始Hutool 大文件下载避坑实战【免费下载链接】hutoolA set of tools that keep Java sweet.项目地址: https://gitcode.com/gh_mirrors/hu/hutool用 Hutool 做文件下载几 MB 的包一行HttpUtil.downloadFile就完事。可一旦换成 8GB 的镜像网抖一下就回到 0——断点续传和大文件下载才是真战场。这两个需求Hutool 的 hutool-http 模块 铺好了地基但没帮你全包有几处坑得自己绕开。HttpUtil.downloadFile 为什么续传不了先说结论也是本文的题眼Hutool 内置的downloadFile系列方法不发Range头永远是裸 GET。long size HttpUtil.downloadFile(url, new File(d:/dl/linux.iso)); // 内部走 createGet writeBody不碰 Range // 网络中断后再调一次还是从 0 开始不是从 60% 继续所以续传这件事你没法靠downloadFile一行搞定得自己构造HttpRequest、自己带Range头、自己判断服务器给的是 206 还是 200。下面这段是续传的全部骨架先把为什么讲透代码反而少。Range 请求被服务器打回 200 怎么办续传的前提是服务器愿意按Range切片返回。请求侧只需两行HttpRequest req HttpRequest.get(url) .header(Range, bytes offset -) // offset 读本地 .part 的当前长度 .timeout(30000); // 异步执行不先把整个 body 读进内存8GB 也不会 OOM HttpResponse resp req.executeAsync();关键是拿到响应后别急着写先看状态码。这就是那个不太明显的坑不少 CDN、代理会直接忽略Range回你一个200加完整文件体。如果你以为在续传、直接用追加模式写前半段旧数据拼上新数据文件就废了。三种状态码的分支处理状态码常量含义你该做什么206HttpStatus.HTTP_PARTIAL服务器认账只给了剩余部分追加写本地.partoffset继续累加200HttpStatus.HTTP_OKRange被忽略返回完整文件删掉.part覆盖从头写别 append416HttpStatus.HTTP_REQUESTED_RANGE_NOT_SATISFIABLE偏移越界多半已下完或文件被改报错或校验完整性别盲目写switch (resp.getStatus()) { case HttpStatus.HTTP_PARTIAL: // 206认账 try (FileOutputStream out new FileOutputStream(file, true)) { resp.writeBody(out, false, overall); // isCloseOutfalse流由上面管 } break; case HttpStatus.HTTP_OK: // 200被打回重下 resp.writeBody(file, overall); // 覆盖写目标文件 break; case HttpStatus.HTTP_REQUESTED_RANGE_NOT_SATISFIABLE: throw new HttpException(offset 越界 offset); }writeBody内部走的是IoUtil.copy的流式拷贝边收边落盘这正是你要的流式写盘。整个交互长这样进度条的 total 为什么总差一截StreamProgress.progress(long total, long progressSize)里的total取自响应的Content-Length。普通下载它是整个文件大小可206 的Content-Length只是剩余那段的长度不是你文件的全长。不处理的话进度条永远在 0~100% 之间来回跳用户就会以为程序卡死。包一层做偏移换算即可StreamProgress overall new StreamProgress() { Override public void progress(long total, long done) { long t total offset, d done offset; Console.log(已下 {}/{} ({}%), t, d, d * 100 / t); } Override public void start() {} Override public void finish() {} };想先拿到分母也可以单独发个 HEADlong total HttpRequest.head(url).execute().contentLength();临时文件为什么多一层 .part 后缀生产里最丑的事故往往是磁盘上躺着一个看起来下载完、其实是半截的文件。两种解法单次下载防半截Hutool 内置了先写临时文件、成功后改名、失败自动删的能力tempFileSuffix默认就是.temp。// 不想自己处理内置版成功才改名成正式文件 HttpDownloader.downloadFile(url, file, .download, 30000, overall);续传不能每次都改名那状态就丢了。这里用固定的.part文件本身当断点状态——它的length()就是下次请求的offset不需要额外的 state 文件天然原子、重启也不丢。一句话.part既当缓冲又当进度记录下载完成前对外只暴露这个中间态完成才FileUtil.rename成正式名。大文件别让 body 先进内存前面那句用executeAsync()不是可有可无。Hutool 里downloadBytes、resp.bodyBytes()这类方法会先把整个 body 读进byte[]——1GB 还好8GB 直接OutOfMemoryError。大文件务必走executeAsync()异步、只持流再writeBody(流)边收边写这才是大文件下载的内存底线。先别急着上多线程分片 看到单线程太慢就掏线程池是个坑。分片加速有个硬前提服务器得支持多段RangeAccept-Ranges允许且真按多段返回否则你分 10 片也是从 0 重下 10 遍。真要上思路是每个线程发独立的Range请求各自seek到预分配好长度的文件对应偏移写自己那片用RandomAccessFile落盘主线程Future.get()汇总——但 Hutool 没现成封装这块得自己搭。对多数业务先把单连接 断点续传做稳往往比上多线程更值也更容易排查。如果你只想记住一件事断点续传能不能成立取决于服务器愿不愿意回 206Hutool 帮你把流式写盘、进度回调和防半截文件铺好了路但Range头、200/206 的分支、以及那个.part状态文件这三样得自己攥在手里。更多细节可对照 官方文档 与HttpResponse源码。【免费下载链接】hutoolA set of tools that keep Java sweet.项目地址: https://gitcode.com/gh_mirrors/hu/hutool创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Codex 免配置一键安装包|本地部署不用敲一行命令

Codex 免配置一键安装包|本地部署不用敲一行命令

前言 做开发的朋友应该都有体会,想要本地部署 Codex,最麻烦的不是软件本身,而是前期环境准备。手动安装 Node.js、处理依赖版本冲突,还要打开终端输入多条命令,稍有不慎就会报错,很多新手卡在这一步直接放…

📅 2026/10/28 10:05:56
HarmonyOS 通知点开只进首页?让通知直接跳到指定业务页面【鸿蒙心迹】

HarmonyOS 通知点开只进首页?让通知直接跳到指定业务页面【鸿蒙心迹】

👋 你好,欢迎来到我的博客!我是【菜鸟学鸿蒙】我是一名在路上的移动端开发者,正从传统“小码农”转向鸿蒙原生开发的进阶之旅。为了把学习过的知识沉淀下来,也为了和更多同路人互相启发,我决定把探索 Harmo…

📅 2026/10/28 10:05:56
my-tv:免费电视直播软件,电视盒子装上就能看

my-tv:免费电视直播软件,电视盒子装上就能看

my-tv:免费电视直播软件,电视盒子装上就能看 【免费下载链接】my-tv 我的电视 电视直播软件,安装即可使用 项目地址: https://gitcode.com/GitHub_Trending/my/my-tv my-tv 是一款开源的电视直播软件,免注册、不收费&#…

📅 2026/10/28 10:05:56
MORE NEWS

更多资讯

📰

连接追踪技术原理与性能优化实践

1. 连接追踪技术概述连接追踪(Connection Tracking)是现代网络系统中实现状态感知的核心机制。不同于传统的无状态数据包处理,连接追踪通过维护连接状态表,使系统能够识别和处理属于同一通信会话的数据包序列。这项技术广泛应用于…

📰

连接追踪技术解析:原理、优化与实战案例

1. 连接追踪技术概述连接追踪(Connection Tracking)是现代网络系统中实现状态感知的核心机制。简单来说,它就像网络通信的"记忆系统",能够识别、记录和管理网络连接的状态变化。这项技术最早出现在防火墙系统中&#xf…

📰

AI工程师转型大模型:技术栈迁移与实战指南

1. AI程序员转型大模型的底层逻辑作为经历过完整技术转型周期的从业者,我深刻理解AI工程师面对大模型浪潮时的焦虑与机遇。2023年大模型技术栈的爆发式增长,让传统AI工程师的技能图谱面临重构。但有趣的是,经过半年实战验证,我发现…

📰

大数据预测模型性能评估:挑战与实践

1. 大数据预测分析模型性能评估的核心挑战在大数据时代,预测分析模型已成为企业决策的重要支撑工具。但面对TB级甚至PB级的数据量、复杂的业务场景和瞬息万变的市场环境,如何准确评估模型性能成为数据科学家面临的首要难题。传统的小规模数据集评估方法在…

📰

Cordys CRM Skills技能套件:智能化客户关系管理新突破

1. Cordys CRM Skills技能发布概述今天要跟大家分享一个企业服务领域的重磅更新——Cordys CRM Skills技能套件正式发布。作为在CRM领域深耕多年的从业者,我第一时间拿到了这套工具的测试权限,经过两周的深度体验,可以负责任地说:…

📰

impeccable:AI编码代理的前端设计质量增强层实战指南

1. 项目缘起与核心定位1.1 一个被名字耽误的实用工具第一次看到 "impeccable" 这个词,很多人会愣一下——这到底是个什么项目?名字取得太文艺了,不像常规技术工具那种直白的命名风格。但恰恰是这个略带"端着"的名字&…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬