在 Java 中下载文件/文件.多线程,这有效



首先,每个人都需要知道我对Java编码比较陌生。更准确地说,我对面向对象编程是完全陌生的。


对于问题。

我正在尝试创建一个下载类,该类更新给定的进度条以显示其进度。可能还有我决定在未来更新的任何其他内容。

目前的问题是,在我看来,这不应该奏效。我可以在"main"方法上做任何我想做的事情,并且 GUI 仍然响应迅速且快速。根据我过去编程的经验,除非我线程化 GUI,否则这是不可能的。这是为什么呢?

既然它有效,可以这样做吗?


类主

package atomicElectronics;
import java.io.IOException;
import atomicElectronics.physical.AtomFrame;
import atomicElectronics.utility.Download;
public class Initial {
    static AtomFrame atomLauncher;
    public static void main(String[] args) {
        atomLauncher = new AtomFrame();
        atomLauncher.start();
        System.out.println(Integer.MAX_VALUE);
        Download theDownload = new Download();
        theDownload.fileProgressBar(atomLauncher.progressBar);
        try {
            theDownload.exicute("http://download.videolan.org/pub/videolan/vlc/last/win64/vlc-2.1.3-win64.exe", "C:\Users\TrinaryAtom\AppData\Roaming");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // TODO Add Download Methods
        // theDownload.updateBarTotal(JProgressBar);
        // theDownload.updateLabelSpeed(String);
        // theDownload.updateLabelTotal(String);
        // theDownload.addFile(File);
        // theDownload.addFiles(Files);
    }
}

类原子帧

package atomicElectronics.physical;
import javax.swing.JFrame;
import java.awt.FlowLayout;
import javax.swing.JProgressBar;
public class AtomFrame extends JFrame{
    public JProgressBar progressBar;
    private static final long serialVersionUID = 4010489530693307355L;
    public static void main(String[] args){
        AtomFrame testFrame = new AtomFrame();
        testFrame.start();
    }
    public AtomFrame(){
        initializeComponents();
    }
    public void initializeComponents(){
        this.setSize(400, 400);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle("Atom Launcher");
        this.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        progressBar = new JProgressBar();
        this.add(progressBar);
        //this.pack();
    }
    public void start() {
        this.setVisible(true);
    }
    public void close() {
        this.dispose();
    }
}

课程下载

package atomicElectronics.utility;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.swing.JProgressBar;
public class Download {
    private static final int BUFFER_SIZE = 4096;
    private JProgressBar fileProgressBar;
    public Download() {
    }
    public void fileProgressBar(JProgressBar fileBar) {
        fileProgressBar = fileBar;
    }
    public void exicute(String fileURL, String saveDir) throws IOException  {
        URL url = new URL(fileURL);
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        int responseCode = httpConn.getResponseCode();
        // always check HTTP response code first
        if (responseCode == HttpURLConnection.HTTP_OK) {
            String fileName = "";
            String disposition = httpConn.getHeaderField("Content-Disposition");
            String contentType = httpConn.getContentType();
            double contentLength = httpConn.getContentLength();
            if (disposition != null) {
                // extracts file name from header field
                int index = disposition.indexOf("filename=");
                if (index > 0) {

          fileName = disposition.substring(index + 9,
                        disposition.length());
            }
        } else {
            // extracts file name from URL
            fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1,
                    fileURL.length());
        }
        System.out.println("Content-Type = " + contentType);
        System.out.println("Content-Disposition = " + disposition);
        System.out.println("Content-Length = " + contentLength);
        System.out.println("fileName = " + fileName);
        // opens input stream from the HTTP connection
        InputStream inputStream = httpConn.getInputStream();
        String saveFilePath = saveDir + File.separator + fileName;
        // opens an output stream to save into file
        FileOutputStream outputStream = new FileOutputStream(saveFilePath);
        double totalRead = 0;
        int bytesRead = -1;
        byte[] buffer = new byte[BUFFER_SIZE];
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
            totalRead += bytesRead;
            System.out.println((totalRead / contentLength) * 100);
            fileProgressBar.setValue((int)((totalRead / contentLength) * 100));
        }
        outputStream.close();
        inputStream.close();
        System.out.println("File downloaded");
    } else {
        System.out.println("No file to download. Server replied HTTP code: " + responseCode);
    }
    httpConn.disconnect();
}

}

建议:

  • 使用 SwingWorker 来执行后台线程工作。
  • 在 Swingworker 中,通过 setProgress(int progress) 设置其进度"绑定"属性。该值应介于 1 和 100 之间。
  • 不要让你的 SwingWorker/文件下载器持有 JProgressBar 或任何 Swing 组件。
  • 将 PropertyChangeListener 添加到 SwingWorker 并监视进度属性中的更改。
  • 切勿公开您的 Swing 字段(或大多数和所有字段)。限制访问,改为通过方法更改对象状态。
  • 阅读教程 Swing 中的并发,了解必要的详细信息。

例如,下面的代码是一个粗略的简化,没有下载任何文件,但应该给你一个想法:

import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Random;
import javax.swing.*;
public class Initial {
   static AtomFrame atomLauncher;
   public static void main(String[] args) {
      atomLauncher = new AtomFrame();
      atomLauncher.start();
      System.out.println(Integer.MAX_VALUE);
      final Download theDownload = new Download();
      theDownload.addPropertyChangeListener(new PropertyChangeListener() {
         @Override
         public void propertyChange(PropertyChangeEvent pcEvt) {
            if ("progress".equals(pcEvt.getPropertyName())) {
               int progress = theDownload.getProgress();
               atomLauncher.setProgress(progress);
            }
         }
      });
      theDownload.execute();
   }
}
class AtomFrame extends JFrame {
   // ********* should be private!
   private JProgressBar progressBar;
   private static final long serialVersionUID = 4010489530693307355L;
   public static void main(String[] args) {
      AtomFrame testFrame = new AtomFrame();
      testFrame.start();
   }
   public void setProgress(int progress) {
      progressBar.setValue(progress);
   }
   public AtomFrame() {
      initializeComponents();
   }
   public void initializeComponents() {
      this.setSize(400, 400);
      this.setLocationRelativeTo(null);
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      this.setTitle("Atom Launcher");
      this.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
      progressBar = new JProgressBar();
      this.add(progressBar);
      // this.pack();
   }
   public void start() {
      this.setVisible(true);
   }
   public void close() {
      this.dispose();
   }
}
class Download extends SwingWorker<Void, Void> {
   private static final long SLEEP_TIME = 300;
   private Random random = new Random();
   @Override
   protected Void doInBackground() throws Exception {
      int myProgress = 0;
      while (myProgress < 100) {
         myProgress += random.nextInt(10);
         setProgress(myProgress);
         try {
            Thread.sleep(SLEEP_TIME);
         } catch (InterruptedException e) {}
      }
      return null;
   }
}

相关内容

最新更新