【问题标题】:Java getting download progressJava获取下载进度
【发布时间】:2014-04-11 22:55:37
【问题描述】:

我正在编写一个 Java 应用程序(使用 NetBeans 作为 IDE 和 jFrame 表单),其中一部分下载了一个文件。如何使用当前下载进度更新进度条,或者至少在另一个线程中获取当前下载的字节总数?

以下是我的部分代码:

Runnable updatethread = new Runnable() {
        public void run() {
            try {
                java.io.BufferedInputStream in = new java.io.BufferedInputStream(new java.net.URL("server/package.zip").openStream());
                java.io.FileOutputStream fos = new java.io.FileOutputStream("package.zip");
                java.io.BufferedOutputStream bout = new BufferedOutputStream(fos,1024);
                byte[] data = new byte[1024];
                int x=0;
                while((x=in.read(data,0,1024))>=0)
                {
                    bout.write(data,0,x);
                }
                bout.close();
                in.close();
            }
            catch(FileNotFoundException e) { } catch (IOException e) { }
        }
    };
new Thread(updatethread).

start();
try {
    updatethread.wait();

} catch (InterruptedException ex) { }

【问题讨论】:

  • @deejay31 一般情况下,遇到{时缩进四个空格或一个制表符,遇到}时取消缩进。

标签: java multithreading swing jframe


【解决方案1】:

我在为上传做进度条时遇到了类似的问题,但解决方案基本相同;创建一个新的 CountingOutputStream 扩展 FileOutputStream 并接受一个可以在写入字节时侦听字节的侦听器。您可以在下面的链接中查看 OutputStreamProgress 类作为示例。

How to get a progress bar for a file upload with Apache HttpClient 4?

看起来 Apache commons IO 已经有一个做类似事情的类。这不完全一样。您必须轮询 OutputStream 以找出它的位置,在我为侦听器提供的解决方案中,回调正在不断更新。

http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/output/CountingOutputStream.html

你可以通过 maven 获取,或者通过他们的网站下载 jar。

Maven -> http://mvnrepository.com/artifact/commons-io/commons-io

罐子 -> http://commons.apache.org/proper/commons-io/download_io.cgi

【讨论】:

    【解决方案2】:
    URL url = new URL(urlString);
    HttpURLConnection httpConnection = (HttpURLConnection) (url.openConnection());
    long fileSize = httpConnection.getContentLength();
    

    注意content-length 是由Http Header 中的服务器提供的。

    函数getContentLength()的API:

    • int java.net.URLConnection.getContentLength()

      返回 content-length 头域的值。

      返回:

      此连接的 URL 资源的内容长度 引用,如果内容长度未知,则为 -1。

    【讨论】:

      【解决方案3】:

      使用您的代码并在进度条中显示进度的工作示例如下所示:

      import java.io.BufferedOutputStream;
      import java.io.FileNotFoundException;
      import java.io.IOException;
      import java.net.HttpURLConnection;
      import java.net.URL;
      
      import javax.swing.JFrame;
      import javax.swing.JProgressBar;
      import javax.swing.SwingUtilities;
      import javax.swing.WindowConstants;
      
      public class Progressbar {
      
          public static void main(String[] args) {
      
              final JProgressBar jProgressBar = new JProgressBar();
              jProgressBar.setMaximum(100000);
              JFrame frame = new JFrame();
              frame.setContentPane(jProgressBar);
              frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
              frame.setSize(300, 70);
              frame.setVisible(true);
      
              Runnable updatethread = new Runnable() {
                  public void run() {
                      try {
      
                          URL url = new URL("http://downloads.sourceforge.net/project/bitcoin/Bitcoin/blockchain/bitcoin_blockchain_170000.zip");
                          HttpURLConnection httpConnection = (HttpURLConnection) (url.openConnection());
                          long completeFileSize = httpConnection.getContentLength();
      
                          java.io.BufferedInputStream in = new java.io.BufferedInputStream(httpConnection.getInputStream());
                          java.io.FileOutputStream fos = new java.io.FileOutputStream(
                                  "package.zip");
                          java.io.BufferedOutputStream bout = new BufferedOutputStream(
                                  fos, 1024);
                          byte[] data = new byte[1024];
                          long downloadedFileSize = 0;
                          int x = 0;
                          while ((x = in.read(data, 0, 1024)) >= 0) {
                              downloadedFileSize += x;
      
                              // calculate progress
                              final int currentProgress = (int) ((((double)downloadedFileSize) / ((double)completeFileSize)) * 100000d);
      
                              // update progress bar
                              SwingUtilities.invokeLater(new Runnable() {
      
                                  @Override
                                  public void run() {
                                      jProgressBar.setValue(currentProgress);
                                  }
                              });
      
                              bout.write(data, 0, x);
                          }
                          bout.close();
                          in.close();
                      } catch (FileNotFoundException e) {
                      } catch (IOException e) {
                      }
                  }
              };
              new Thread(updatethread).
      
              start();
          }
      
      }
      

      这说明了如何做到这一点 - 在使用它之前,您应该考虑 GUI-Threads 等。

      【讨论】:

      • PS:如 Jazzepi 所述,使用现有库可能是一个更好的主意 - 如果您的项目环境允许您使用外部库。
      • 您的代码会下载文件,但不会自行关闭/退出。
      猜你喜欢
      • 2023-04-02
      • 2018-10-05
      • 2011-07-26
      • 2018-04-27
      • 1970-01-01
      • 2020-10-14
      • 2013-04-21
      • 1970-01-01
      • 2022-08-09
      相关资源
      最近更新 更多