如何在C#中以编程方式下载大文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2269607/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to programmatically download a large file in C#
提问by hIpPy
I need to programmatically download a large file before processing it. What's the best way to do that? As the file is large, I want to specific time to wait so that I can forcefully exit.
我需要在处理之前以编程方式下载一个大文件。这样做的最佳方法是什么?由于文件很大,我想在特定的时间等待,以便我可以强制退出。
I know of WebClient.DownloadFile(). But there does not seem a way to specific an amount of time to wait so as to forcefully exit.
我知道 WebClient.DownloadFile()。但是似乎没有办法指定等待的时间以强制退出。
try
{
WebClient client = new WebClient();
Uri uri = new Uri(inputFileUrl);
client.DownloadFile(uri, outputFile);
}
catch (Exception ex)
{
throw;
}
Another way is to use a command line utility (wget) to download the file and fire the command using ProcessStartInfo and use Process' WaitForExit(int ms) to forcefully exit.
另一种方法是使用命令行实用程序 (wget) 下载文件并使用 ProcessStartInfo 触发命令,并使用 Process' WaitForExit(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;
}
Is there a better way? Please help. Thanks.
有没有更好的办法?请帮忙。谢谢。
采纳答案by Remus Rusanu
Use a WebRequestand get the response stream. Then read from the reponse Stream blocks of bytes, and write each block to the destination file. This way you can control when to stop if the download takes too long, as you get control between chunks and you can decide if the download has timed out based on a clock:
使用WebRequest并获取响应流。然后从响应 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);
}
}
}
回答by BFree
How about using DownloadFileAsync
in the WebClient class. The cool thing about going this route is that you can cancel the operation by calling CancelAsync
if it takes too long. Basically, call this method, and if a specified amount of time elapses, call Cancel.
DownloadFileAsync
在 WebClient 类中使用如何。走这条路线很酷的一点是,CancelAsync
如果时间太长,您可以通过调用取消操作。基本上,调用此方法,如果经过指定的时间量,则调用 Cancel。
回答by orip
Asked here: C#: Downloading a URL with timeout
在这里提问:C#:下载带有超时的 URL
Simplest solution:
最简单的解决方案:
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();
}
}
Better (more flexible) solution is this answerto the same question, in the form of a WebClientWithTimeout
helper class.
更好(更灵活)的解决方案是以辅助类的形式回答同一问题WebClientWithTimeout
。
回答by Daniel Caballero
You can use DownloadFileAsync
as @BFree said and then try with the following WebClient's events
您可以DownloadFileAsync
像@BFree 所说的那样使用,然后尝试使用以下 WebClient 的事件
protected virtual void OnDownloadProgressChanged(DownloadProgressChangedEventArgs e);
protected virtual void OnDownloadFileCompleted(AsyncCompletedEventArgs e);
Then you can know the Progress Percentage
然后你就可以知道进度百分比
e.ProgressPercentage
Hope this helps
希望这可以帮助