2011-01-15 52 views
13

Tôi làm cách nào để sử dụng thư viện để tải xuống tệp và in ra các byte được lưu? Tôi đã thử sử dụngTải xuống tệp bằng cách sử dụng commons java apache?

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

nhưng tôi không thể hiển thị byte hoặc thanh tiến trình. Tôi nên sử dụng phương pháp nào?

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

Trả lời

13

Nếu bạn đang tìm cách lấy tổng số byte trước khi tải xuống, bạn có thể nhận được giá trị này từ tiêu đề Content-Length trong phản hồi http.

Nếu bạn chỉ muốn số byte cuối cùng sau khi tải xuống, cách dễ nhất là kiểm tra kích thước tệp bạn vừa viết.

Tuy nhiên nếu bạn muốn hiển thị tiến độ hiện tại có bao nhiêu byte đã được tải về, bạn có thể muốn mở rộng apache CountingOutputStream để quấn FileOutputStream để mọi việc write phương pháp này được gọi là nó đếm số byte đi qua và cập nhật thanh tiến trình.

Cập nhật

Đây là một thực hiện đơn giản của DownloadCountingOutputStream. Tôi không chắc chắn nếu bạn đã quen thuộc với việc sử dụng ActionListener hay không nhưng nó là một lớp hữu ích để thực hiện 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)); 
     } 
    } 

} 

Đây là mẫu sử dụng:

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

Làm cách nào để mở rộng apache để sử dụng? fl = new File (System.getProperty ("user.home") thay thế ("\\", "/") + "/Desktop/Screenshots.zip"); dl = URL mới ("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip"); OutputStream os = new FileOutputStream (fl); InputStream là = dl.openStream(); CountingOutputStream count = new CountingOutputStream (os); dl.openConnection().getHeaderField ("Content-Length"); IOUtils.copy (là, os); // bắt đầu chuyển Tôi có làm đúng không? – Kyle

+0

Bạn có nhớ thêm mã ở trên vào câu hỏi của mình không? Thật khó đọc. Tôi sẽ cố gắng giúp đỡ. – gigadot

+0

Tôi đã thêm mã cảm ơn bạn đã trợ giúp. – Kyle

10

commons-ioIOUtils.copy(inputStream, outputStream). Vì vậy:

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

IOUtils.copy(is, os); 

IOUtils.toByteArray(is) có thể được sử dụng để lấy byte.

Lấy tổng số byte là một câu chuyện khác. Luồng không cung cấp cho bạn tổng số - chúng chỉ có thể cung cấp cho bạn những gì hiện có sẵn trong luồng. Nhưng vì đó là một dòng, nó có thể có nhiều hơn.

Đó là lý do tại sao http có cách đặc biệt để chỉ định tổng số byte. Nó nằm trong tiêu đề phản hồi Content-Length. Vì vậy, bạn phải gọi url.openConnection() và sau đó gọi getHeaderField("Content-Length") trên đối tượng URLConnection. Nó sẽ trả về số byte dưới dạng chuỗi. Sau đó, sử dụng Integer.parseInt(bytesString) và bạn sẽ nhận được tổng số của mình.

+0

Hmm .. là có một cách để hiển thị các byte tải về từ suối đó? Tôi đang tìm kiếm nhưng tôi không thấy một cách nào. Cảm ơn vi đa trả lơi. – Kyle

+0

'IOUtils.toByteArray (..)' – Bozho

+0

btw, các byte hoặc số đếm của chúng? – Bozho

Các vấn đề liên quan