小编典典

用Java下载文件。多线程,这行得通吗?

java

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


问题。

我试图创建一个下载类来更新进度条,以显示其进度。可能还有其他决定,我决定在以后进行更新。

目前的问题是,在我看来,这不起作用。我可以在“主要”方法上做任何我想做的事情,而且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);
    }

}

类AtomFrame

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();

}

}


阅读 226

收藏
2020-11-30

共1个答案

小编典典

意见建议:

  • 使用SwingWorker进行后台线程工作。
  • 在您的SwingWorker内部,通过设置其进度“ bound”属性setProgress(int progress)。该值应在1到100之间。
  • 不要让您的SwingWorker /文件下载器拥有JProgressBar或任何Swing组件。
  • 将PropertyChangeListener添加到您的SwingWorker,并监视progress属性中的更改。
  • 切勿将您的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;
   }
}
2020-11-30