代码之家  ›  专栏  ›  技术社区  ›  hIpPy

如何用C语言编程下载大文件#

  •  7
  • hIpPy  · 技术社区  · 15 年前

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

    我知道webclient.downloadfile()。但似乎没有办法确定等待的具体时间,以便强行退出。

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

    另一种方法是使用命令行实用程序(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;
    }
    

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

    4 回复  |  直到 10 年前
        1
  •  18
  •   Qubei Pyramid Newbie    10 年前

    使用A WebRequest 然后得到 response 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);
                    }
                }
            }
    
        2
  •  7
  •   BFree    15 年前

    用一下怎么样 DownloadFileAsync 在webclient类中。走这条路线最酷的地方是你可以打电话取消操作 CancelAsync 如果时间太长。基本上,调用这个方法,如果经过指定的时间,调用cancel。

        3
  •  3
  •   Community CDub    8 年前

    问到这里: 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
  •  2
  •   Daniel Caballero    12 年前

    你可以用 DownloadFileAsync 正如@bfree所说,然后尝试以下webclient事件

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

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

    e.ProgressPercentage
    

    希望这有帮助