我需要在处理之前以编程方式下载大文件。最好的方法是什么?由于文件很大,我想要特定的时间等待,以便我可以强行退出。
我知道WebClient.DownloadFile()。但似乎没有办法确定等待一段时间以便强行退出。
try
{
WebClient client = new WebClient();
Uri uri = new Uri(inputFileUrl);
client.DownloadFile(uri, outputFile);
}
catch (Exception ex)
{
throw;
}
另一种方法是使用命令行实用程序(wget)下载文件并使用ProcessStartInfo触发命令并使用Process'WellForExit(int ms)强制退出。
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 :(得分:18)
使用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);
}
}
}
答案 1 :(得分:7)
如何在WebClient类中使用DownloadFileAsync
。走这条路线很酷的一点是,如果花费的时间过长,可以通过调用CancelAsync
来取消操作。基本上,调用此方法,如果超过指定的时间,请调用Cancel。
答案 2 :(得分:3)
在这里问: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
辅助类的形式。
答案 3 :(得分:2)
您可以使用DownloadFileAsync
作为@BFree说,然后尝试使用以下WebClient的事件
protected virtual void OnDownloadProgressChanged(DownloadProgressChangedEventArgs e);
protected virtual void OnDownloadFileCompleted(AsyncCompletedEventArgs e);
然后您就可以知道进度百分比
e.ProgressPercentage
希望这有帮助