9
votes

Comment télécharger par programme un gros fichier en C #

J'ai besoin de télécharger par programme un fichier volumineux avant de le traiter. Quelle est la meilleure façon de faire ça? Comme le fichier est grand, je veux une heure précise pour attendre de sorte que je puisse sortir avec force.

Je sais de webclient.downloadfile (). Mais il ne semble pas qu'un moyen de spécifiquer une quantité de temps pour attendre de manière à sortir avec force. P>

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


1 commentaires

J'ai essayé le premier et ça marche bien.


4 Réponses :


24
votes

Utilisez un WebRequest et obtenir le Response flux . Ensuite, lisez à partir des blocs de flux de répare d'octets et écrivez chaque bloc dans le fichier de destination. De cette façon, vous pouvez contrôler quand arrêter si le téléchargement prend trop de temps, car vous obtenez le contrôle entre les morceaux et vous pouvez décider si le téléchargement a expiré en fonction d'une horloge:

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


4 commentaires

@orip, comment est-ce compliqué?


@Juan, pour celui qu'il est synchrone. La version asynchrone de cet exemple serait très différente. Mais aussi, il jette la façade WebClient très conviviale qui masque les trucs de gestion de flux qui sont largement pertinents 90% du temps.


ORIP, votre code est beaucoup plus simple. Un avantage d'utiliser le code Remus 'est que je peux le téléchargement de la partie du fichier.


@HLPPY: Si vous préférez le webclient.downloadfileAseync / Cancelasync, vous pouvez utiliser l'événement WebClient.DownloadProgressSchangedChanged pour connaître la progression.



8
votes

Que diriez-vous d'utiliser downloadfileAseync dans la classe WebClient. La chose cool à propos de ce itinéraire est que vous pouvez annuler l'opération en appelant annulasync s'il faut trop de temps. Fondamentalement, appelez cette méthode et si une quantité de temps spécifiée s'élève, appelez Annuler.


1 commentaires

Si une partie du fichier a été téléchargée, annulasync conserve cette partie ou la supprime?



3
votes

Demandé ici: C #: Téléchargement d'une URL avec délai d'attente

Solution la plus simple: p>

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


1 commentaires

Le WebRequest.Timeout ne mesure que le temps jusqu'à la réception des en-têtes de réponse HTTP, pas le temps total jusqu'à la téléchargement du corps de réponse. C'est à dire. Cela affecte le temps jusqu'à ce que GetResponse revienne.



2
votes

Vous pouvez utiliser téléchargerfileasync code> comme @bfree a dit, puis essayez avec les événements de WebClient suivants xxx pré>

alors vous pouvez connaître le pourcentage de progrès p>

e.ProgressPercentage


0 commentaires