2011-01-15 85 views
13

如何使用库下载文件并打印保存的字节?我尝试使用使用java apache commons下载文件?

import static org.apache.commons.io.FileUtils.copyURLToFile; 
public static void Download() { 

     URL dl = null; 
     File fl = null; 
     try { 
      fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/Screenshots.zip"); 
      dl = new URL("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip"); 
      copyURLToFile(dl, fl); 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
    } 

但我不能显示字节或一个进度条。我应该使用哪种方法?

public class download { 
    public static void Download() { 
     URL dl = null; 
     File fl = null; 
     String x = null; 
     try { 
      fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/Screenshots.zip"); 
      dl = new URL("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip"); 
      OutputStream os = new FileOutputStream(fl); 
      InputStream is = dl.openStream(); 
      CountingOutputStream count = new CountingOutputStream(os); 
      dl.openConnection().getHeaderField("Content-Length"); 
      IOUtils.copy(is, os);//begin transfer 

      os.close();//close streams 
      is.close();//^ 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
    } 

回答

13

如果您正在寻找一种在下载前获取总字节数的方法,您可以从http响应中的Content-Length标头中获取该值。

如果你只是想下载后的最终字节数,最简单的方法是检查刚刚写入的文件大小。

但是,如果你想显示的多少字节已下载的最新进展,您可能要扩展Apache CountingOutputStream包裹FileOutputStream使每次的write方法被调用它计数通过字节和更新的数进度条。

更新

下面是一个简单的实施DownloadCountingOutputStream。我不确定你是否熟悉使用ActionListener,但它是实现GUI的有用类。

public class DownloadCountingOutputStream extends CountingOutputStream { 

    private ActionListener listener = null; 

    public DownloadCountingOutputStream(OutputStream out) { 
     super(out); 
    } 

    public void setListener(ActionListener listener) { 
     this.listener = listener; 
    } 

    @Override 
    protected void afterWrite(int n) throws IOException { 
     super.afterWrite(n); 
     if (listener != null) { 
      listener.actionPerformed(new ActionEvent(this, 0, null)); 
     } 
    } 

} 

这是使用样品:

public class Downloader { 

    private static class ProgressListener implements ActionListener { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      // e.getSource() gives you the object of DownloadCountingOutputStream 
      // because you set it in the overriden method, afterWrite(). 
      System.out.println("Downloaded bytes : " + ((DownloadCountingOutputStream) e.getSource()).getByteCount()); 
     } 
    } 

    public static void main(String[] args) { 
     URL dl = null; 
     File fl = null; 
     String x = null; 
     OutputStream os = null; 
     InputStream is = null; 
     ProgressListener progressListener = new ProgressListener(); 
     try { 
      fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/Screenshots.zip"); 
      dl = new URL("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip"); 
      os = new FileOutputStream(fl); 
      is = dl.openStream(); 

      DownloadCountingOutputStream dcount = new DownloadCountingOutputStream(os); 
      dcount.setListener(progressListener); 

      // this line give you the total length of source stream as a String. 
      // you may want to convert to integer and store this value to 
      // calculate percentage of the progression. 
      dl.openConnection().getHeaderField("Content-Length"); 

      // begin transfer by writing to dcount, not os. 
      IOUtils.copy(is, dcount); 

     } catch (Exception e) { 
      System.out.println(e); 
     } finally { 
      IOUtils.closeQuietly(os); 
      IOUtils.closeQuietly(is); 
     } 
    } 
} 
+0

我将如何扩展Apache来使用它? fl = new File(System.getProperty(“user.home”)。replace(“\\”,“/”)+“/Desktop/Scr​​eenshots.zip”); dl = new URL(“http://ds-forums.com/kyle-tests/uploads/Screenshots.zip”); OutputStream os = new FileOutputStream(fl); InputStream is = dl.openStream(); CountingOutputStream count = new CountingOutputStream(os); dl.openConnection()。的getHeaderField( “内容长度”); IOUtils.copy(is,os); //开始传输 我在做对吧? – Kyle

+0

你介意把上面的代码附加到你的问题上吗?这很难阅读。我会尽力帮助。 – gigadot

+0

我加了代码谢谢你的帮助。 – Kyle

10

commons-ioIOUtils.copy(inputStream, outputStream)。所以:

OutputStream os = new FileOutputStream(fl); 
InputStream is = dl.openStream(); 

IOUtils.copy(is, os); 

而且IOUtils.toByteArray(is)可以用来获取字节。

获取总字节数是一个不同的故事。数据流不会给你任何总数 - 它们只能给你当前流中可用的内容。但由于它是一个流,它可能会有更多的来。

这就是为什么http有特殊的方式来指定总字节数。它在响应标题Content-Length中。因此,您必须致电url.openConnection(),然后致电URLConnection对象上的getHeaderField("Content-Length")。它将以字符串形式返回字节数。然后使用Integer.parseInt(bytesString),你会得到你的总数。

+0

嗯..有以显示来自该流下载的字节的方法吗?我在看,但我没有看到一种方式。谢谢回复。 – Kyle

+0

'IOUtils.toByteArray(..)' – Bozho

+0

btw,字节本身,还是它们的计数? – Bozho

相关问题