2010-02-15 44 views
6

我需要处理它之前以编程方式下载大文件。什么是最好的方式来做到这一点?由于文件很大,我想要特定的时间等待,以便我可以强制退出。如何以编程方式下载大文件在C#中

我知道WebClient.DownloadFile的()。但似乎没有办法确定等待时间来强制退出。

try 
{ 
    WebClient client = new WebClient(); 
    Uri uri = new Uri(inputFileUrl); 
    client.DownloadFile(uri, outputFile); 
} 
catch (Exception ex) 
{ 
    throw; 
} 

的另一种方法是使用命令行实用程序(wget的)要下载的文件,并触发使用的ProcessStartInfo和使用过程WaitForExit命令(INT毫秒)强行退出。

ProcessStartInfo startInfo = new ProcessStartInfo(); 
//set startInfo object 

try 
{ 
    using (Process exeProcess = Process.Start(startInfo)) 
    { 
     //wait for time specified 
     exeProcess.WaitForExit(1000 * 60 * 60);//wait till 1m 

     //check if process has exited 
     if (!exeProcess.HasExited) 
     { 
      //kill process and throw ex 
      exeProcess.Kill(); 
      throw new ApplicationException("Downloading timed out"); 
     } 
    } 
} 
catch (Exception ex) 
{ 
    throw; 
} 

有没有更好的方法?请帮忙。谢谢。

+0

什么是URI ?这是FTP吗? – t0mm13b 2010-02-15 23:20:27

回答

16

使用WebRequest,并获得response stream。然后从响应Stream字节块中读取,并将每个块写入目标文件。这样,您就可以控制何时停止,如果下载需要太长时间,因为你得到的块之间的控制,你可以决定是否下载已经基于时钟超时:           

 DateTime startTime = DateTime.UtcNow; 
     WebRequest request = WebRequest.Create("http://www.example.com/largefile"); 
     WebResponse response = request.GetResponse(); 
     using (Stream responseStream = response.GetResponseStream()) { 
      using (Stream fileStream = File.OpenWrite(@"c:\temp\largefile")) { 
       byte[] buffer = new byte[4096]; 
       int bytesRead = responseStream.Read(buffer, 0, 4096); 
       while (bytesRead > 0) {  
        fileStream.Write(buffer, 0, bytesRead); 
        DateTime nowTime = DateTime.UtcNow; 
        if ((nowTime - startTime).TotalMinutes > 5) { 
         throw new ApplicationException(
          "Download timed out"); 
        } 
        bytesRead = responseStream.Read(buffer, 0, 4096); 
       } 
      } 
     } 
+0

@orip,它是如何复杂? – juan 2010-02-16 00:07:17

+0

@Juan,对于一个它是同步的。这个例子的异步版本看起来非常不同。但它也抛出了非常用户友好的WebClient外观,90%的时间隐藏了很大程度上不相关的流管理内容。 – Josh 2010-02-16 00:15:10

+1

orip,你的代码要简单得多。使用Remus代码的一个优点是我可以下载多少文件。 – hIpPy 2010-02-16 19:59:20

7

如何关于在WebClient类中使用DownloadFileAsync。大约走这条路很酷的事情是,你可以通过调用CancelAsync如果时间太长取消操作。基本上,调用这个方法,如果经过了指定的时间,调用Cancel。

4

这里问:C#: Downloading a URL with timeout

简单的解决方案:

public string GetRequest(Uri uri, int timeoutMilliseconds) 
{ 
    var request = System.Net.WebRequest.Create(uri); 
    request.Timeout = timeoutMilliseconds; 
    using (var response = request.GetResponse()) 
    using (var stream = response.GetResponseStream()) 
    using (var reader = new System.IO.StreamReader(stream)) 
    { 
     return reader.ReadToEnd(); 
    } 
} 

更好(更灵活)的解决方案是this answer对同一问题,在WebClientWithTimeout辅助类的形式。

+4

webrequest.timeout只测量直到收到HTTP响应头的时间,而不是直到响应正文被下载的总时间。 IE浏览器。它会影响GetResponse返回之前的时间。 – 2010-02-16 00:08:58

+0

好点,我没有意识到这一点 – orip 2010-02-16 00:29:16

2

您可以使用DownloadFileAsync作为@BFree说,然后尝试用下面的Web客户端的事件

protected virtual void OnDownloadProgressChanged(DownloadProgressChangedEventArgs e); 
protected virtual void OnDownloadFileCompleted(AsyncCompletedEventArgs e); 

然后你就可以知道进度百分比

e.ProgressPercentage 

希望这有助于

相关问题