2008-10-22 9 views
2

J'essaie de faire fonctionner ce morceau de code un peu mieux. Je pense que c'est la boucle qui lit un octet à la fois. Je ne pouvais pas trouver une autre façon de le faire avec la décompression gzip. L'implémentation d'un StreamReader est correcte, mais elle renvoie une chaîne que je ne peux pas transmettre au flux de décompression.C# télécharger une page Web. Un meilleur moyen est nécessaire, l'utilisation du processeur est élevée

Y a-t-il un meilleur moyen?

byte[] bufffer = null; 
List<byte> resourceBytes = new List<byte>(); 
int byteValue = 0; 
WebResource resource = new WebResource(); 
HttpWebResponse webResponse = null; 

try { 
    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(resourceUri); 
    webRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate"); 
    webRequest.Headers.Add(HttpRequestHeader.AcceptCharset, "ISO-8859-1,utf-8;q=0.7,*;q=0.7"); 
    webRequest.UserAgent = agent; 
    webRequest.Accept = "text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1"; 
    webRequest.Credentials = CredentialCache.DefaultCredentials; 
    webRequest.Referer = resourceUri.OriginalString; 
    webRequest.Timeout = 5000; 

    webResponse = (HttpWebResponse)webRequest.GetResponse(); 

    Stream webStream = webResponse.GetResponseStream(); 

    if (!string.IsNullOrEmpty(webResponse.ContentEncoding)) { 
     if (webResponse.ContentEncoding.ToLower().Contains("gzip")) { 
      webStream = new GZipStream(webStream, CompressionMode.Decompress); 
     } 
     else if (webResponse.ContentEncoding.ToLower().Contains("deflate")) { 
      webStream = new DeflateStream(webStream, CompressionMode.Decompress); 
     } 
    } 

    do { 
     byteValue = webStream.ReadByte(); 

     if (byteValue != -1) { 
      resourceBytes.Add((byte)byteValue); 
     } 

    } while (byteValue != -1); 


    //Free up resources 
    webStream.Close(); 
    webResponse.Close(); 

    bufffer = resourceBytes.ToArray(); 

Répondre

9

Je suis d'accord avec jmcd que WebClient serait beaucoup plus simple , en particulier WebClient.DownloadData.

re la question réelle, le problème est que vous lisez les octets, lorsque vous devriez probablement avoir un tampon fixe et boucle - à savoir

int bytesRead; 
byte[] buffer = new byte[1024]; 
while((bytesRead = webStream.Read(buffer, 0, buffer.Length)) > 0) { 
    // process "bytesRead" worth of data from "buffer" 
} 

[modifier ajouter l'accent] Le bit important est que vous seulement processus "bytesRead" valeur de données chaque fois; tout ce qui est au-delà est la poubelle.

+0

Bonne réponse.Ceci est probablement la cause de la lenteur – samjudson

+0

Correct - vous posté ce que je préparais une réponse en disant la même .... – NotJarvis

+1

Sir Psycho - comment puis-je dire assez sur ce point fort: vous avez tort ... –

1

Est-ce que la classe WebClient ne sert à rien de ce que vous voulez faire?

+0

WebClient fonctionne correctement si je n'utilise pas de compression. Sa ressemblance à peut avoir à –

+0

WebClient ne supporte pas la décompression :( –

0

Si vous voulez la réponse en tant que chaîne vous pouvez le faire.

String ReponseText; 

IO.StreamReader ResponseReader = New IO.StreamReader(webStream); 
ReponseText= ResponseReader.ReadToEnd(); 

Si vous voulez un octet réel Tableau faire (Désolé, Ne vous sentez pas comme la conversion en C# pour celui-ci)

'Declare Array Same size as response 
Dim ResponseData(webStream .Length) As Byte 
'Read all the data at once 
webStream.Read(ResponseData, 0, webStream .Length) 
+0

N'a-t-il pas dit qu'il avait un problème avec l'utilisation d'une chaîne de streamreader? – NotJarvis

Questions connexes