2010-08-05 6 views
21

Я пытаюсь загрузить большой файл с моего Yahoo! сервер веб-сайта, который, по-видимому, настроен (не мной), чтобы отключить загрузки, если они не завершены в течение 100 секунд. Файл достаточно мал, чтобы обычно успешно переносить. В случаях, когда скорость передачи данных медленная и загрузка отключается, существует ли способ возобновить URLConnection при смещении файла, где произошло отключение? Вот код:Как возобновить прерванный скачать

// 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

Возможно использовать что-то другое, чем сервер Yahoo веб-сайт :) У Android нет возможностей «scp»? Какая здесь большая картина? –

ответ

29

Попробуйте использовать «Range» заголовок запроса:

// 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(); 

Сделав это, вы можете seek в данной точке (как раз перед длиной данных скачать, скажем X) и начните записывать недавно загруженные данные. Обязательно используйте то же значение X для заголовка диапазона.

Подробная информация о 14.35.2 Range Retrieval Requests

Более подробную информацию и исходный код можно найти here

+3

Приятным примером, вероятно, следует проверить, что код ответа на сервере составляет 206 «Частичный контент», чтобы убедиться, что он поддерживает запрос диапазона байтов. –

+1

naikus, спасибо за помощь. Я все еще читаю документ w3 и надеюсь найти причину, по которой Yahoo! сервер всегда передается с начала файла, а не с начала указанного диапазона. Дальнейшие попытки описаны в part 2 этого вопроса. – gregS

+0

Получил ответ от Yahoo! технической поддержки, заявив, что Yahoo! серверы не поддерживают запросы диапазона байтов: «Yahoo! Web Hosting не поддерживает заголовок Accept-range, поскольку мы работаем с пулом серверов, и каждый запрос потенциально достигает другого сервера. В заголовке ответа вы увидите соединение = [закрыть] указывая на это ». – gregS

0

Вот пример кода, который вы можете использовать:

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(); 
      } 
     } 
    } 
}  
Смежные вопросы