2017-10-21 44 views
0

Je suis en train d'écrire un composant pour streamer un gros (4+ Go) à partir d'un service HTTP. Le composant prend un URL et un flux de destination. Le flux de destination peut être un flux de fichiers ou un flux POST vers un service HTTP différent, voire les deux. Comme l'auteur de mon élément, je dois faire ces étapes jusqu'à ce que je fait:Diffuser un fichier volumineux à partir du service http

  1. lire un tampon de taille raisonnable du flux HTTP,
  2. écrire ce tampon au flux de destination,
  3. Vider le flux de destination (sur disque, réseau, etc)

Je ne devrais jamais avoir plus que la taille du tampon de données en mémoire. J'utilise flurl pour faire mes appels HTTP au serveur. J'ai essayé les façons de faire mon appel

var stream = await flurlClient.GetStreamAsync(); 

Cela me rend un MemoryStream, qui ne fonctionne pas comme ça va remplir et prendre autant de mémoire que la taille du fichier.

var response = flurlClient.GetAsync(); 
var stream = response.Content.ReadAsStreamAsync(); 

Encore une fois, un flux de mémoire.

var response = flurlClient.GetAsync(); 
var stream = new CustomFlushingSteam(); 
response.Content.CopyToAsync(stream); 

Celui-ci semble prometteur, mais hélas, il essaie d'écrire le tout en utilisant une seule instruction Write().

Comment puis-je accomplir cette tâche sans faire exploser ma mémoire? Je préférerais utiliser flurl, mais je ne suis pas lié à ça.

+0

Flurl vous donne-t-il accès au 'NetworkStream' sous-jacent? Sinon, ça ne marchera pas pour ça –

Répondre

1

Après avoir fait quelques recherches, je trouve que le code suivant résout mon problème:

var response = flurlClient.SendAsync(
    HttpMethod.Get, null, null, HttpCompletionOption.ResponseHeadersRead); 
var stream = response.Content.ReadAsStreamAsync(); 

Dans ce cas, le courant qui revient n'est plus un flux de mémoire, mais le flux réseau.

+0

Oui, c'est ce que tu veux faire. Et c'est ce que [DownloadFileAsync] de Flurl (https://github.com/tmenier/Flurl/blob/master/src/Flurl.Http/DownloadExtensions.cs#L24) fait en interne. –