如何以编程方式下载C#中的大文件

时间:2010-02-15 23:10:39

标签: c# webclient download large-files

我需要在处理之前以编程方式下载大文件。最好的方法是什么?由于文件很大,我想要特定的时间等待,以便我可以强行退出。

我知道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;
}

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

4 个答案:

答案 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

希望这有帮助