|
JAVA大文件切片下载,断点续传。
在 Java 中实现大文件的切片下载和断点续传功能,可以通过 HTTP Range 请求来实现。以下是一个示例,展示了如何实现大文件的切片下载和断点续传。
### 一、服务器端
首先,创建一个简单的 Java 服务器来提供文件下载功能。我们将使用 `HttpServlet` 来处理文件下载请求,并支持 Range 请求。
- ```java
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- @WebServlet("/download")
- public class FileDownloadServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String filePath = "path/to/your/largefile.zip"; // 替换为实际文件路径
- File file = new File(filePath);
- long fileLength = file.length();
- String range = request.getHeader("Range");
- if (range != null) {
- // 处理 Range 请求
- String[] ranges = range.replace("bytes=", "").split("-");
- long start = Long.parseLong(ranges[0]);
- long end = fileLength - 1;
- if (ranges.length > 1) {
- end = Long.parseLong(ranges[1]);
- }
- response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
- response.setContentLength((int) (end - start + 1));
- response.setHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileLength);
- response.setContentType("application/octet-stream");
- try (FileInputStream inStream = new FileInputStream(file)) {
- inStream.skip(start);
- byte[] buffer = new byte[4096];
- long bytesToSend = end - start + 1;
- long bytesSent = 0;
- while (bytesSent < bytesToSend) {
- int bytesRead = inStream.read(buffer, 0, (int) Math.min(buffer.length, bytesToSend - bytesSent));
- if (bytesRead == -1) break;
- response.getOutputStream().write(buffer, 0, bytesRead);
- bytesSent += bytesRead;
- }
- }
- } else {
- // 处理普通请求
- response.setContentType("application/octet-stream");
- response.setContentLength((int) fileLength);
- response.setHeader("Content-Disposition", "attachment; filename="" + file.getName() + """);
- try (FileInputStream inStream = new FileInputStream(file);
- OutputStream outStream = response.getOutputStream()) {
- byte[] buffer = new byte[4096];
- int bytesRead;
- while ((bytesRead = inStream.read(buffer)) != -1) {
- outStream.write(buffer, 0, bytesRead);
- }
- }
- }
- }
- }
- ```
复制代码
### 二、客户端
接下来,创建一个 Java 客户端来下载文件并实现断点续传和切片下载功能。
- ```java
- import java.io.*;
- import java.net.HttpURLConnection;
- import java.net.URL;
- public class FileDownloader {
- public static void downloadFile(String fileURL, String saveDir) {
- try {
- File file = new File(saveDir);
- long existingFileSize = 0;
- // 如果文件已经存在,获取其大小
- if (file.exists()) {
- existingFileSize = file.length();
- }
- // 创建 URL 对象并打开连接
- URL url = new URL(fileURL);
- HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
- httpConn.setRequestMethod("GET");
- // 设置 Range 请求头
- if (existingFileSize > 0) {
- httpConn.setRequestProperty("Range", "bytes=" + existingFileSize + "-");
- }
- // 连接服务器
- httpConn.connect();
- // 检查响应代码
- if (httpConn.getResponseCode() == HttpURLConnection.HTTP_PARTIAL || httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
- // 获取输入流
- InputStream inputStream = httpConn.getInputStream();
- RandomAccessFile raf = new RandomAccessFile(file, "rw");
- raf.seek(existingFileSize); // 移动到文件末尾
- byte[] buffer = new byte[4096]; // 4KB 缓冲区
- int bytesRead;
- while ((bytesRead = inputStream.read(buffer)) != -1) {
- raf.write(buffer, 0, bytesRead);
- }
- raf.close();
- inputStream.close();
- System.out.println("文件下载成功: " + saveDir);
- } else {
- System.out.println("服务器响应代码: " + httpConn.getResponseCode());
- }
- httpConn.disconnect();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public static void main(String[] args) {
- String fileURL = "http://localhost:8080/download"; // 替换为实际的文件 URL
- String saveDir = "C:/path/to/save/largefile.zip"; // 替换为保存的路径
- downloadFile(fileURL, saveDir);
- }
- }
- ```
复制代码
### 代码说明
1. **服务器端**:
- 使用 `HttpServlet` 创建一个文件下载的 Servlet。
- 处理 HTTP Range 请求,以支持断点续传。
- 读取文件并将其写入响应中。
2. **客户端**:
- 使用 `HttpURLConnection` 发送 GET 请求以下载文件。
- 如果文件已经存在,则发送 Range 请求,以便从断点续传。
- 使用 `RandomAccessFile` 在文件中移动到指定位置,以便在断点续传时从上次下载的位置继续。
### 注意事项
- 确保服务器能够正确处理 Range 请求,并且客户端能够正确发送 Range 请求。
- 处理异常时,可以根据需要添加更详细的错误处理逻辑。
- 在实际应用中,可以根据需要添加多线程下载和进度显示等功能。
通过以上代码,你可以实现大文件的切片下载和断点续传功能。
|
|