2010-08-05 119 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

也许使用非雅虎网站服务器以外的东西:) Android没有'scp'功能吗?这里的大图是什么? – 2010-08-05 03:16:09

回答

29

尝试使用“范围”请求头:

// 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“Partial Content”,以确保它支持字节范围请求。 – 2010-08-05 09:08:27

+1

奈克斯,感谢您的帮助。我仍然在阅读w3文档,希望找到雅虎的原因。服务器似乎总是从文件的开头传输而不是从指定范围的开始传输。在这个问题的part 2中描述了进一步的尝试。 – gregS 2010-08-07 15:58:35

+0

我收到了Yahoo!的回复。技术支持说雅虎!服务器不支持字节范围请求: “由于我们使用服务器池并且每个请求可能到达不同服务器,因此Yahoo!虚拟主机不支持Accept-range标头,并且您会在响应头中看到connection = [close]表明这一点。“ – gregS 2010-08-11 11:11:57

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