Java断点续传需网络协议(Range头/206响应)、RandomAccessFile随机写入、断点信息持久化三者协同;缺一不可,普通流无法直接实现。

Java 中无法直接通过普通流(如 InputStream/OutputStream)实现断点续传,因为断点续传本质是**网络协议层+服务端协同**的功能,核心依赖 HTTP 的 Range 请求头和服务器对分块响应的支持(如返回 206 Partial Content)。Java 流本身只负责本地数据读写,不处理网络状态、偏移记录、失败恢复等逻辑。要实现断点续传,必须结合网络请求控制、本地文件随机写入、断点位置持久化三部分。
1. 用 HttpURLConnection 或 OkHttp 发送带 Range 的请求
客户端需明确告诉服务器“从哪个字节开始下载”。关键步骤:
- 检查本地已下载文件大小(即已成功写入的字节数),作为起始偏移
start - 设置请求头:
connection.setRequestProperty("Range", "bytes=" + start + "-") - 发送请求后,检查响应码是否为
206(不是200),否则说明服务器不支持断点续传或范围无效 - 读取响应体时,跳过已下载部分,从
start位置开始追加写入
2. 使用 RandomAccessFile 实现本地文件随机写入
普通 FileOutputStream 默认覆盖或追加,无法在指定位置写入。必须用 RandomAccessFile 定位并写入:
- 以读写模式打开:
new RandomAccessFile(file, "rw") - 定位到断点位置:
raf.seek(start) - 从网络输入流中读取数据,逐段写入:
raf.write(buffer, 0, len) - 写完及时调用
raf.getChannel().force(true)确保数据落盘,避免断电丢失
3. 持久化断点信息,避免内存丢失
程序崩溃或用户关闭后,必须能恢复上次进度。不能只靠内存变量:
将后端 Java 接口文档转换为前端 TypeScript 类型定义(interface / type)。输入:飞书文档、Spring Boot 接口文档、Swagger/OpenAPI、手写 API 文档等。输出:包含请求参数与响应结果的 .md 文件,含完整 JSDoc 注释。触发关键词:Java 转 TS、接口转换、生成前端类型、接口文档转 TypeScript、DTO/VO/BO 转 interface、后端文档转前端类型、生成接口类型、类型定义生成。
立即学习“Java免费学习笔记(深入)”;
- 将当前已下载字节数(
currentSize)、总大小(可从Content-Range响应头解析)、URL、文件路径等存到本地小文件(如 JSON 或 properties)或数据库 - 每次写入数据后,立即更新断点文件(建议加简单锁或使用原子写入,如先写临时文件再 rename)
- 启动续传前,先读取断点文件,验证本地文件长度是否匹配;若不一致(如被手动删改),则重新开始或提示错误
4. 处理常见异常与重试逻辑
网络不稳定时需健壮恢复:
- 捕获
IOException、SocketTimeoutException等,记录当前 offset 后退出,不丢弃已下载数据 - 实现指数退避重试(如 1s、2s、4s…),避免频繁重连压垮服务端
- 校验完整性:下载完成后可用 MD5/SHA256 对比服务端提供的摘要值,不一致则删除重下
- 注意大文件长时间下载的内存占用——始终用固定大小缓冲区(如 8KB),避免一次性读全响应体
不复杂但容易忽略

















