用HttpURLConnection实现断点续传需先HEAD请求校验Accept-Ranges,再依file.length()动态设Range头,响应206时解析Content-Range校验总长,最后用RandomAccessFile以rwd模式seek到start追加写入。

用 HttpURLConnection 实现断点续传,核心就是正确构造和解析 Range 请求头与 Content-Range 响应头。关键不在于“变量”本身,而在于动态计算起始位置、校验服务器支持、处理响应状态,并安全追加写入文件。
检查服务器是否支持断点续传
不能直接发 Range 请求,必须先确认服务端能力。发送一个 HEAD 请求,检查响应头中是否存在:
- Accept-Ranges: bytes —— 明确表示支持字节范围请求
- 或 Accept-Ranges: none / 缺失该字段 —— 不支持,需全量重下
若支持,再读取 Content-Length 获取文件总大小,为后续 range 计算提供依据。
动态计算 Range 起始位置
起始字节由本地已下载文件长度决定,不是硬编码的变量:
- 创建目标 File 对象,调用 file.length() 获取当前字节数(即已成功写入的偏移量)
- 若文件不存在或为空,start = 0;否则 start = file.length()
- 设置请求头:connection.setRequestProperty("Range", "bytes=" + start + "-")
注意:末尾的短横线 "-" 表示“从 start 到文件末尾”,比写死 end 更稳妥(避免因总大小变化导致越界)。
正确处理 206 响应与 Content-Range
收到响应后,必须验证状态码和范围信息:
- 响应码必须是 HttpURLConnection.HTTP_PARTIAL(206),不是 200
- 读取响应头 Content-Range,例如:bytes 1024-4999/5000
- 从中解析出总大小(斜杠后数字),与 HEAD 请求获取的值比对,防止服务端内容变更
- 若解析失败或不一致,建议清空临时文件并重新开始
用 RandomAccessFile 安全追加写入
普通 FileOutputStream 无法精准定位写入位置,必须用 RandomAccessFile:
- 以 "rwd" 模式打开(同步写入磁盘,保障断电不丢数据)
- 调用 raf.seek(start) 将写入指针移到已下载末尾
- 逐块读取 InputStream 并写入,避免内存溢出
- 写完后 close(),确保缓冲区刷盘
这样即使多次中断重启,文件内容始终连续、无覆盖、无错位。

















