2011-01-15 21 views
13

¿Cómo puedo usar la biblioteca para descargar un archivo e imprimir los bytes guardados? Intenté usarDescargar archivo usando Java Common 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); 
     } 
    } 

pero no puedo mostrar los bytes o una barra de progreso. ¿Qué método debo usar?

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

Respuesta

13

Si está buscando una forma de obtener el número total de bytes antes de la descarga, puede obtener este valor del encabezado Content-Length en la respuesta http.

Si solo desea el número final de bytes después de la descarga, es más fácil verificar el tamaño del archivo en el que acaba de escribir.

Sin embargo, si desea mostrar los avances actuales de cuántos bytes se han descargado, es posible que desee ampliar Apache CountingOutputStream para envolver el FileOutputStream de manera que cada vez que los métodos write se llaman Cuenta el número de bytes que pasan a través y actualización la barra de progreso.

actualización

Aquí es una implementación sencilla de DownloadCountingOutputStream. No estoy seguro si está familiarizado con el uso de ActionListener o no, pero es una clase útil para implementar la 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)); 
     } 
    } 

} 

Ésta es la muestra de uso:

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

¿Cómo extendería apache para usar eso? 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 ¿Lo estoy haciendo bien? – Kyle

+0

¿Le importaría agregar el código anterior a su pregunta? Es difícil de leer. Trataré de ayudar. – gigadot

+0

Agregué el código, gracias por ayudarme. – Kyle

10

commons-io tiene IOUtils.copy(inputStream, outputStream). Por lo tanto:

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

IOUtils.copy(is, os); 

Y IOUtils.toByteArray(is) se puede utilizar para obtener los bytes.

Obtener el número total de bytes es una historia diferente. Las transmisiones no le dan ningún total; solo le pueden dar lo que está actualmente disponible en la transmisión. Pero dado que es un flujo, puede tener más por venir.

Es por eso que http tiene su forma especial de especificar el número total de bytes. Está en el encabezado de respuesta Content-Length. Por lo tanto, debe llamar al url.openConnection() y luego llamar al getHeaderField("Content-Length") en el objeto URLConnection. Devolverá el número de bytes como cadena. Luego use Integer.parseInt(bytesString) y obtendrá el total.

+0

Hmm .. no es una forma de mostrar los bytes descargados de esa corriente? Estoy buscando pero no veo la manera. Gracias por la respuesta. – Kyle

+0

'IOUtils.toByteArray (..)' – Bozho

+0

por cierto, ¿los bytes mismos o su conteo? – Bozho