天天看點

【第86題】JAVA進階技術-網絡程式設計5(斷點續傳)

文章目錄

  • ​​零、前言​​
  • ​​一、題目描述​​
  • ​​二、解題思路​​
  • ​​三、代碼詳解​​
  • ​​四、推薦專欄​​
  • ​​五、示例源碼下載下傳​​

一、題目描述

題目實作:網絡資源的斷點續傳功能。

二、解題思路

擷取要下載下傳的資源網址

顯示網絡資源的大小

上次讀取到的位元組位置以及未讀取的位元組數

輸入下載下傳的起始位置和結束位置,開始下載下傳網絡資源

如果沒有下載下傳完成,可以接着上次的下載下傳位置繼續下載下傳

建立一個類:BreakPointSuperveneFrame,繼承JFrame窗體類。

定義一個download()方法:用于實作網絡資源的斷點續傳。

核心重點:通過設定請求參數RANGE實作,通過RANGE參數可以指定下載下傳網絡的位元組區間,進而可以實作每次下載下傳部分網絡資源的功能

例如:将該參數設定為“RANGEbytes=0-1024”,就表示将網絡資源中從0~1024之間的内容下載下傳到客戶機;如果将該參數設定為“RANGE:bytes=1024-”,就表示将網絡資源中從1024到結束位置的内容全部下載下傳到客戶機。

測試下載下傳這個連結:http://xz.w10a.com/small/FeiRarInstall.rar

三、代碼詳解

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       xiaoxuzhu       2022/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();
        }
    }
}      
【第86題】JAVA進階技術-網絡程式設計5(斷點續傳)

點選開始下載下傳,提示要–》輸入位址後回車

【第86題】JAVA進階技術-網絡程式設計5(斷點續傳)

輸入位址後回車,會擷取檔案的大小

【第86題】JAVA進階技術-網絡程式設計5(斷點續傳)

嘗試先下載下傳 0-1024 ,下載下傳後,會自動計算未下載下傳的起始和結束位置。

【第86題】JAVA進階技術-網絡程式設計5(斷點續傳)

下載下傳後,寫入本地檔案,檔案存儲在D:盤目錄下

【第86題】JAVA進階技術-網絡程式設計5(斷點續傳)

下載下傳成功提示:

【第86題】JAVA進階技術-網絡程式設計5(斷點續傳)

檔案存儲在D:盤目錄下

【第86題】JAVA進階技術-網絡程式設計5(斷點續傳)

四、推薦專欄

​​《JAVA從零到壹》​​

​​《JAVA築基100例》​​

五、示例源碼下載下傳