2011-01-15 7 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 헤더에서이 값을 얻을 수 있습니다.

다운로드 후 최종 바이트 수만 원하면 방금 쓰는 파일 크기를 확인하는 것이 가장 쉽습니다. 당신이 다운로드 한 얼마나 많은 바이트의 현재 진행 상황을 표시하려는 경우

그러나이 때문에 write 방법이라고 그 때마다이 통과 바이트 업데이트의 수를 계산 FileOutputStream 포장 아파치 CountingOutputStream을 확장 할 수 있습니다 진행률 표시 줄.

업데이트 여기

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

어떻게 아파치를 사용하겠습니까? fl = new File (System.getProperty ("user.home"). replace ("\\", "/") + "/Desktop/Screenshots.zip"); dl = 새 URL ("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip"); OutputStream os = 새로운 FileOutputStream (fl); InputStream is = dl.openStream(); CountingOutputStream 개수 = 새 CountingOutputStream (os); dl.openConnection().getHeaderField ("Content-Length"); 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

관련 문제