How to programmatically load a large file in C #

I need to programmatically download a large file before processing it. What's the best way to do this? Since the file is large, I want to specify a specific time to wait so that I can force exit.

I know WebClient.DownloadFile (). But there doesn't seem to be a way to a certain amount of time to wait to be forced to exit.

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

      

Another way is to use the command line utility (wget) to download the file and run the command using ProcessStartInfo and force the Process WaitForExit (int ms) to exit the process.

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. Thank.

+7


source to share


4 answers


Use WebRequest and get a response stream . Then read streaming byte blocks from the answers and write each block to a destination file. This way you can control when to stop if the download is taking too long as you gain control between chunks and you can decide if the download timeout was based on hours:    



        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);
                }
            }
        }

      

+18


source


How about using it DownloadFileAsync

in the WebClient class. The hunt for this route is that you can undo the operation by calling CancelAsync

if it takes too long. Basically, call this method, and if a certain amount of time has elapsed, call Cancel.



+7


source


Asked here: C #: Loading url with timeout

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();
    }
}

      

A better (more flexible) solution is this answer to the same question as a helper class WebClientWithTimeout

.

+4


source


You can use DownloadFileAsync

like @BFree and then try with following WebClient events

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

      

Then you can know the Progress Percentage

e.ProgressPercentage

      

Hope it helps

+2


source







All Articles