Java实现断点续传功能的示例代码

作者:小虚竹and掘金 时间:2021-12-27 10:07:56 

一、题目描述

题目实现:网络资源的断点续传功能。

二、解题思路

获取要下载的资源网址

显示网络资源的大小

上次读取到的字节位置以及未读取的字节数

输入下载的起始位置和结束位置,开始下载网络资源

如果没有下载完成,可以接着上次的下载位置继续下载

创建一个类:BreakPointSuperveneFrame,继承JFrame窗体类。

定义一个download()方法:用于实现网络资源的断点续传。

核心重点:通过设置请求参数RANGE实现,通过RANGE参数可以指定下载网络的字节区间,从而可以实现每次下载部分网络资源的功能

例如:将该参数设置为“RANGEbytes=0-1024”,就表示将网络资源中从0~1024之间的内容下载到客户机;如果将该参数设置为“RANGE:bytes=1024-”,就表示将网络资源中从1024到结束位置的内容全部下载到客户机。

测试下载这个链接

三、代码详解

BreakPointSuperveneFrame

package com.xiaoxuzhu;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

/**
* Description:
*
* @author xiaoxuzhu
* @version 1.0
*
* <pre>
* 修改记录:
* 修改后版本        修改人修改日期修改内容
* 2022/5/29.1    xiaoxuzhu2022/5/29    Create
* </pre>
* @date 2022/5/29
*/
public class BreakPointSuperveneFrame extends JFrame {
   private JTextField tf_totalLength;
   private JTextField tf_residuaryLength;
   private JTextField tf_readToPos;
   private JTextField tf_address;
   private JTextField tf_endPos;
   private JTextField tf_startPos;
   private String urlAddress = "";// 用于存储网络资源的地址
   private long totalLength = 0;// 存储网络资源的大小,以字节为单位
   private long readToPos = 0;// 存储上次读取到的位置
   private long residuaryLength = 0;// 存储未读内容的大小

/**
    * Launch the application
    *
    * @param args
    */
   public static void main(String args[]) {
       EventQueue.invokeLater(new Runnable() {
           public void run() {
               try {
                   BreakPointSuperveneFrame frame = new BreakPointSuperveneFrame();
                   frame.setVisible(true);
               } catch (Exception e) {
                   e.printStackTrace();
               }
           }
       });
   }

/**
    * Create the frame
    */
   public BreakPointSuperveneFrame() {
       super();
       getContentPane().setLayout(null);
       setTitle("下载网络资源的断点续传");
       setBounds(100, 100, 514, 238);
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

tf_startPos = new JTextField();
       tf_startPos.setBounds(80, 165, 113, 22);
       getContentPane().add(tf_startPos);

final JLabel label = new JLabel();
       label.setText("起始位置:");
       label.setBounds(10, 167, 74, 18);
       getContentPane().add(label);

final JLabel label_1 = new JLabel();
       label_1.setText("结束位置:");
       label_1.setBounds(199, 167, 74, 18);
       getContentPane().add(label_1);

tf_endPos = new JTextField();
       tf_endPos.setBounds(267, 165, 117, 22);
       getContentPane().add(tf_endPos);

final JLabel label_2 = new JLabel();
       label_2.setText("网络资源的地址:");
       label_2.setBounds(10, 52, 113, 18);
       getContentPane().add(label_2);

tf_address = new JTextField();
       tf_address.addActionListener(new ActionListener() {
           public void actionPerformed(final ActionEvent e) {
               try {
                   urlAddress = tf_address.getText().trim();
                   URL url = new URL(urlAddress);// 获得网络资源的URL
                   HttpURLConnection connection = (HttpURLConnection) url
                           .openConnection();// 获得连接对象
                   connection.connect();// 连接网络资源
                   totalLength = connection.getContentLength();// 获得网络资源的长度
                   connection.disconnect();// 断开连接
                   tf_totalLength.setText(String.valueOf(totalLength));// 显示总长度
                   tf_readToPos.setText("0");// 显示上次读取到的位置
                   residuaryLength = totalLength;// 未读内容为文件总长度
                   tf_residuaryLength.setText(String.valueOf(residuaryLength));// 显示未读内容
               } catch (MalformedURLException e1) {
                   e1.printStackTrace();
               } catch (IOException e2) {
                   e2.printStackTrace();
               }

}
       });
       tf_address.setBounds(119, 50, 365, 22);
       getContentPane().add(tf_address);

final JLabel label_3 = new JLabel();
       label_3.setForeground(new Color(0, 0, 255));
       label_3.setFont(new Font("", Font.BOLD, 14));
       label_3.setText("输入网络资源的地址并回车,可以获得网络资源的大小。");
       label_3.setBounds(10, 10, 384, 22);
       getContentPane().add(label_3);

final JLabel label_4 = new JLabel();
       label_4.setForeground(new Color(128, 0, 0));
       label_4.setText("网络资源的大小为");
       label_4.setBounds(10, 76, 113, 38);
       getContentPane().add(label_4);

final JLabel label_5 = new JLabel();
       label_5.setText("上次读取到");
       label_5.setBounds(10, 123, 74, 18);
       getContentPane().add(label_5);

tf_readToPos = new JTextField();
       tf_readToPos.setBounds(80, 121, 113, 22);
       tf_readToPos.setEnabled(false);
       getContentPane().add(tf_readToPos);

final JLabel label_6 = new JLabel();
       label_6.setText("字节处,还剩");
       label_6.setBounds(202, 123, 87, 18);
       getContentPane().add(label_6);

tf_residuaryLength = new JTextField();
       tf_residuaryLength.setBounds(285, 120, 117, 22);
       tf_residuaryLength.setEnabled(false);
       getContentPane().add(tf_residuaryLength);

final JLabel label_7 = new JLabel();
       label_7.setText("字节未读。");
       label_7.setBounds(404, 123, 80, 18);
       getContentPane().add(label_7);

final JLabel label_4_1 = new JLabel();
       label_4_1.setForeground(new Color(128, 0, 0));
       label_4_1.setText("个字节。");
       label_4_1.setBounds(404, 76, 80, 38);
       getContentPane().add(label_4_1);

tf_totalLength = new JTextField();
       tf_totalLength.setBounds(119, 84, 283, 22);
       tf_totalLength.setEnabled(false);
       getContentPane().add(tf_totalLength);

final JButton button = new JButton();
       button.setBounds(395, 162, 89, 28);
       getContentPane().add(button);
       button.addActionListener(new ActionListener() {
           public void actionPerformed(final ActionEvent e) {
               if (totalLength == 0) {
                   JOptionPane.showMessageDialog(null,
                           "没有网络资源。\n\n请输入正确的网址,然后回车。");
                   return;
               }
               long startPos = 0;// 起始位置
               long endPos = 0;// 结束位置
               try {
                   startPos = Long.parseLong(tf_startPos.getText().trim());// 起始位置
                   endPos = Long.parseLong(tf_endPos.getText().trim());// 结束位置
               } catch (Exception ex) {
                   JOptionPane.showMessageDialog(null, "输入的起始位置或结束位置不正确。");
                   return;
               }
               readToPos = endPos;// 记录读取到的位置
               residuaryLength = totalLength - readToPos;// 记录未读内容的大小
               tf_readToPos.setText(String.valueOf(readToPos));// 显示读取到的位置
               tf_residuaryLength.setText(String.valueOf(residuaryLength));// 显示未读字节数
               tf_startPos.setText(String.valueOf(readToPos));// 设置下一个读取点的开始位置
               tf_endPos.setText(String.valueOf(totalLength));// 设置下一个读取点的结束位置
               tf_endPos.requestFocus();// 使结束位置文本框获得焦点
               tf_endPos.selectAll();// 选择结束位置文本框中的全部内容,方便输入结束位置值
               download(startPos, endPos);// 调用方法进行下载
           }
       });
       button.setText("开始下载");
   }

public void download(long startPosition, long endPosition) {
       try {
           URL url = new URL(urlAddress);// 获得网络资源的URL
           HttpURLConnection connection = (HttpURLConnection) url
                   .openConnection();// 获得连接对象
           connection.setRequestProperty("User-Agent", "NetFox");// 设置请求属性
           String rangeProperty = "bytes=" + startPosition + "-";// 定义请求范围属性
           if (endPosition > 0) {
               rangeProperty += endPosition;// 调整请求范围属性
           }
           connection.setRequestProperty("RANGE", rangeProperty);// 设置请求范围属性
           connection.connect();// 连接网络资源
           InputStream in = connection.getInputStream();// 获得输入流对象
           String file = url.getFile();// 获得文件对象
           String name = file.substring(file.lastIndexOf('/') + 1);// 获得文件名
           FileOutputStream out = new FileOutputStream("d:/" + name, true);// 创建输出流对象,保存下载的资源
           byte[] buff = new byte[2048];// 创建字节数组
           int len = 0;// 定义存储读取内容长度的变量
           len = in.read(buff);// 读取内容
           while (len != -1) {
               out.write(buff, 0, len);// 写入磁盘
               len = in.read(buff);// 读取内容
           }
           out.close();// 关闭流
           in.close();// 关闭流
           connection.disconnect();// 断开连接
           if (readToPos > 0 && readToPos == totalLength) {
               JOptionPane.showMessageDialog(null, "完成网络资源的下载。\n单击“确定”按钮退出程序。");
               System.exit(0);
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
   }
}

Java实现断点续传功能的示例代码

点击开始下载,提示要--》输入地址后回车

Java实现断点续传功能的示例代码

输入地址后回车,会获取文件的大小

Java实现断点续传功能的示例代码

尝试先下载 0-1024 ,下载后,会自动计算未下载的起始和结束位置。

Java实现断点续传功能的示例代码

下载后,写入本地文件,文件存储在D:盘目录下

Java实现断点续传功能的示例代码

下载成功提示:

Java实现断点续传功能的示例代码

文件存储在D:盘目录下

Java实现断点续传功能的示例代码

来源:https://juejin.cn/post/7154239564469993480

标签:Java,断点续传
0
投稿

猜你喜欢

  • 简单了解Java编程中抛出异常的方法

    2023-08-07 17:31:49
  • C# 一个WCF简单实例

    2023-07-12 20:53:43
  • Android 如何获取手机总内存和可用内存等信息

    2023-07-27 13:11:42
  • 关于Java反编译字节码文件

    2021-10-07 01:41:32
  • 小议Java中final关键字使用时的注意点

    2022-12-04 08:40:45
  • JavaWeb框架MVC设计思想详解

    2022-09-09 06:43:50
  • Java 反射调用静态方法的简单实例

    2021-10-09 06:47:58
  • SpringBoot注入自定义的配置文件的方法详解

    2021-12-24 02:28:06
  • 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic

    2022-03-26 18:43:02
  • 为什么不要使用 async void的原因分析

    2023-11-24 21:10:27
  • JavaSwing FlowLayout 流式布局的实现

    2023-10-02 03:59:41
  • JDK14新特性之switch表达式的实现

    2022-06-01 17:49:31
  • spring boot 集成 shiro 自定义密码验证 自定义freemarker标签根据权限渲染不同页面(推荐

    2023-07-28 17:39:16
  • Android编程实现WebView添加进度条的方法

    2023-07-06 03:16:46
  • java实现京东秒杀功能分享 京东秒杀软件

    2021-09-10 23:27:36
  • RabbitMQ开启SSL与SpringBoot连接测试的配置方法

    2023-09-25 14:40:30
  • 华为鸿蒙系统应用开发工具 DevEco Studio的安装和使用图文教程

    2022-09-14 05:04:23
  • Springboot初始化项目并完成登入注册的全过程

    2023-07-31 15:09:09
  • MyBatis3源码解析之如何获取数据源详解

    2023-12-06 02:23:08
  • mybatis postgresql 批量删除操作方法

    2021-07-19 17:13:56
  • asp之家 软件编程 m.aspxhome.com