2011-01-15 124 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

相關問題