2010-08-05 22 views
21

Estoy intentando descargar un archivo grande de mi Yahoo! servidor de sitio web que aparentemente está configurado (no por mí) para desconectar las descargas si no se completan dentro de los 100 segundos. El archivo es lo suficientemente pequeño para poder transferirlo con éxito. En las ocasiones en que la velocidad de datos es lenta y la descarga se desconecta, ¿hay alguna manera de reanudar el URLConnection en el offset del archivo donde se produjo la desconexión? Aquí está el código:cómo reanudar una descarga interrumpida

// Setup connection. 
URL url = new URL(strUrl[0]); 
URLConnection cx = url.openConnection(); 
cx.connect(); 

// Setup streams and buffers. 
int lengthFile = cx.getContentLength(); 
InputStream input = new BufferedInputStream(url.openStream()); 
OutputStream output = new FileOutputStream(strUrl[1]); 
byte data[] = new byte[1024]; 

// Download file. 
for (total=0; (count=input.read(data, 0, 1024)) != -1; total+=count) { 
    publishProgress((int)(total*100/lengthFile)); 
    output.write(data, 0, count); 
    Log.d("AsyncDownloadFile", "bytes: " + total); 
} 

// Close streams. 
output.flush(); 
output.close(); 
input.close(); 
+1

Quizás usar algo distinto al servidor del sitio web de Yahoo :) ¿Android no tiene capacidades 'scp'? ¿Cuál es el panorama general aquí? –

Respuesta

29

Trate de usar un "Rango" encabezado de la solicitud:

// Open connection to URL. 
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 

// Specify what portion of file to download. 
connection.setRequestProperty("Range", "bytes=" + downloaded + "-"); 
// here "downloaded" is the data length already previously downloaded. 

// Connect to server. 
connection.connect(); 

Una vez hecho esto, puede seek en un punto dado (justo antes de la longitud de los datos de descarga, por ejemplo X) y comienza a escribir los datos recién descargados allí. Asegúrese de utilizar el mismo valor X para el encabezado del rango.

Los detalles sobre 14.35.2 Range Retrieval Requests

Más detalles y el código fuente se pueden encontrar here

+3

Buen ejemplo, probablemente debería verificar que el código de respuesta del servidor sea 206 "Contenido parcial", para asegurarse de que admite la solicitud de rango de bytes. –

+1

naikus, gracias por la ayuda. Todavía estoy leyendo el documento w3 y espero encontrar la razón por la cual Yahoo! el servidor parece transmitir siempre desde el principio del archivo en lugar de desde el principio del rango especificado. Se describen intentos adicionales en part 2 de esta pregunta. – gregS

+0

Recibí una respuesta de Yahoo! soporte técnico diciendo que el Yahoo! los servidores no son compatibles con solicitudes de rango de bytes: "Yahoo Web Hosting no es compatible con el encabezado Aceptar rango ya que trabajamos con un grupo de servidores y cada solicitud potencialmente llega a un servidor diferente. Verás conexión = [cerrar] en el encabezado de respuesta indicando esto ". – gregS

0

Aquí hay un código de ejemplo que puede utilizar:

import java.io.*; 
import java.net.*; 


public class HttpUrlDownload { 

    public static void main(String[] args) { 
     String strUrl = "http://VRSDLSCEN001:80//DLS//lib//clics.jar"; 
     String DESTINATION_PATH = "clics.jar"; 

     int count = 0; 
     while (true) { 
      count++; 
      if (download(strUrl, DESTINATION_PATH) == true || count > 20) { 
      break; 
      }   
     } 
    } 

    public static boolean download(String strUrl, String DESTINATION_PATH) { 
     BufferedInputStream in = null; 
     FileOutputStream fos = null; 
     BufferedOutputStream bout = null; 
     URLConnection connection = null; 

     int downloaded = 0; 

     try { 
      System.out.println("mark ... download start"); 
      URL url = new URL(strUrl); 

      connection = url.openConnection(); 

      File file=new File(DESTINATION_PATH); 
      if(file.exists()){ 
       downloaded = (int) file.length(); 
      } 
      if (downloaded == 0) { 
       connection.connect(); 
      } 
      else { 
       connection.setRequestProperty("Range", "bytes=" + downloaded + "-"); 
       connection.connect(); 
      } 

      try { 
       in = new BufferedInputStream(connection.getInputStream()); 
      } catch (IOException e) { 
       int responseCode = 0; 
       try { 
        responseCode = ((HttpURLConnection)connection).getResponseCode(); 
       } catch (IOException e1) { 
       e1.printStackTrace(); 
       } 

       if (responseCode == 416) {   
        return true; 
       } else { 
        e.printStackTrace(); 
        return false; 
       } 
      } 

      fos=(downloaded==0)? new FileOutputStream(DESTINATION_PATH): new FileOutputStream(DESTINATION_PATH,true); 
      bout = new BufferedOutputStream(fos, 1024); 

      byte[] data = new byte[1024]; 
      int x = 0; 
      while ((x = in.read(data, 0, 1024)) >= 0) { 
       bout.write(data, 0, x); 
      } 

      in.close(); 
      bout.flush(); 
      bout.close(); 
      return false; 

     } catch (IOException e) { 
      e.printStackTrace(); 
      return false; 
     } finally { 
      if (in != null) { 
       try { 
        in.close(); 
       } catch (IOException e) { 
       } 
      } 
      if (fos != null) { 
       try { 
        fos.close(); 
       } catch (IOException e) { 
       } 
      } 
      if (bout != null) { 
       try { 
        bout.close(); 
       } catch (IOException e) { 
       } 
      } 

      if (connection != null) { 
       ((HttpURLConnection)connection).disconnect(); 
      } 
     } 
    } 
}  
Cuestiones relacionadas