java如何分段下载
分段下载的实现方法
在Java中实现分段下载(多线程下载或分块下载)通常通过HttpURLConnection或第三方库如OkHttp完成。以下是核心步骤和代码示例:
使用HttpURLConnection实现分段下载
设置请求头获取文件总大小
通过Range头指定下载范围,服务器返回206 Partial Content状态码表示支持分段下载。

URL url = new URL("http://example.com/file.zip");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Range", "bytes=0-"); // 初始请求获取文件大小
long fileSize = connection.getContentLengthLong();
分块下载逻辑 创建多个线程,每个线程负责下载文件的一个片段,最后合并文件。
int threadCount = 4; // 线程数
long chunkSize = fileSize / threadCount;
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
for (int i = 0; i < threadCount; i++) {
long start = i * chunkSize;
long end = (i == threadCount - 1) ? fileSize - 1 : start + chunkSize - 1;
executor.submit(() -> downloadChunk(url, start, end, i));
}
executor.shutdown();
单线程分块下载实现

private void downloadChunk(URL url, long start, long end, int threadId) throws IOException {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Range", "bytes=" + start + "-" + end);
try (InputStream in = conn.getInputStream();
RandomAccessFile raf = new RandomAccessFile("output.part" + threadId, "rw")) {
raf.seek(start);
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
raf.write(buffer, 0, len);
}
}
}
使用OkHttp简化实现
OkHttp内置对分段下载的支持,代码更简洁:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://example.com/file.zip")
.header("Range", "bytes=0-1023") // 下载前1KB
.build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
try (InputStream in = response.body().byteStream();
FileOutputStream out = new FileOutputStream("part1")) {
byte[] buf = new byte[8192];
int bytesRead;
while ((bytesRead = in.read(buf)) != -1) {
out.write(buf, 0, bytesRead);
}
}
}
}
文件合并与校验
下载完成后,需将所有分块合并为一个文件,并校验完整性:
try (FileOutputStream fos = new FileOutputStream("final_file.zip")) {
for (int i = 0; i < threadCount; i++) {
Files.copy(Paths.get("output.part" + i), fos);
}
}
// 可选:通过MD5或文件大小校验完整性
注意事项
- 服务器支持:确保服务器支持
Range请求(检查响应头Accept-Ranges: bytes)。 - 线程管理:避免过多线程导致资源竞争,通常4-8个线程足够。
- 断点续传:记录已下载的字节位置,异常恢复时从断点继续。
- 错误处理:捕获
IOException并重试失败的分块。
通过上述方法,可以高效实现大文件的分段下载,充分利用带宽资源。






