Comment télécharger un fichier volumineux (via HTTP) in.NET?

Je dois télécharger un fichier large (2 Go) sur HTTP dans une application console c#. Problème est, après environ 1,2 GO, l'application manque de mémoire.

Voici le code que j'utilise:

WebClient request = new WebClient();
request.Credentials = new NetworkCredential(username, password);
byte[] fileData = request.DownloadData(baseURL + fName);

Comme vous pouvez le voir... Je lis le fichier directement en mémoire. Je suis sûr que je pourrais résoudre cela si je devais lire les données de HTTP en morceaux et les écrire dans un fichier sur le disque.

Comment pourrais-je faire ça?

21
demandé sur Peter Mortensen 2009-07-03 13:19:40

5 réponses

Si vous utilisez WebClient.DownloadFile Vous pouvez l'enregistrer directement dans un fichier.

35
répondu Alex Peck 2009-07-03 09:25:00

La classe WebClient est celle des scénarios simplifiés. Une fois que vous avez passé des scénarios simples( et vous avez), vous devrez vous replier un peu et utiliser WebRequest.

Avec WebRequest, vous aurez accès au flux de réponses, et vous pourrez le parcourir en boucle, en lisant un peu et en écrivant un peu, jusqu'à ce que vous ayez terminé.


Exemple:

public void MyDownloadFile(Uri url, string outputFilePath)
{
    const int BUFFER_SIZE = 16 * 1024;
    using (var outputFileStream = File.Create(outputFilePath, BUFFER_SIZE))
    {
        var req = WebRequest.Create(url);
        using (var response = req.GetResponse())
        {
            using (var responseStream = response.GetResponseStream())
            {
                var buffer = new byte[BUFFER_SIZE];
                int bytesRead;
                do
                {
                    bytesRead = responseStream.Read(buffer, 0, BUFFER_SIZE);
                    outputFileStream.Write(buffer, 0, bytesRead);
                } while (bytesRead > 0);
            }
        }
    }
}

Notez que si WebClient.DownloadFile fonctionne, alors je l'appellerais la meilleure solution. J'ai écrit ce qui précède avant la réponse "DownloadFile" a été posté. Je l'ai aussi écrit trop tôt le matin, donc un grain de sel (et de test) peut être nécessaire.

28
répondu John Saunders 2009-07-03 09:32:53

Vous devez obtenir le flux de réponse, puis lire en blocs, en écrivant chaque bloc dans un fichier pour permettre la réutilisation de la mémoire.

Comme vous l'avez écrit, toute la réponse, tous les 2 Go, doit être en mémoire. Même sur un système 64 bits qui atteindra la limite de 2 Go pour un seul objet. net.


Mise à jour: option plus facile. Get WebClient pour faire le travail pour vous: avec son DownloadFile méthode qui permettra de mettre les données directement dans un fichier.

9
répondu Richard 2009-07-03 09:21:33

WebClient.OpenRead renvoie un flux, il suffit d'utiliser Read pour parcourir le contenu, de sorte que les données ne sont pas mises en mémoire tampon mais peuvent être écrites en blocs dans un fichier.

3
répondu Whuppa 2013-01-25 09:36:30

Je voudrais utiliser quelque chose comme ce

2
répondu Sadegh 2009-07-03 09:30:11