C # en téléchargeant une page Web. Une meilleure façon de procéder, utilisation du processeur élevée

StackOverflow https://stackoverflow.com/questions/225617

  •  03-07-2019
  •  | 
  •  

Question

J'essaie de faire en sorte que ce code fonctionne un peu mieux. Je suppose que c'est la boucle qui lit un octet à la fois. Je ne pouvais pas trouver un autre moyen de faire cela avec la décompression gzip. L'implémentation de StreamReader convient, mais renvoie une chaîne que je ne peux pas transmettre au flux de décompression.

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();
Était-ce utile?

La solution

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

En ce qui concerne la question, le problème est que vous lisez des octets, alors que vous devriez probablement avoir un tampon fixe et une boucle - c’est-à-dire.

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

[modifier pour ajouter une emphase] Le bit important est que vous seulement traitez "bytesRead". valeur des données à chaque fois; au-delà, il y a des déchets.

Autres conseils

Le WebClient la classe ne sert à rien pour ce que vous voulez faire?

Si vous souhaitez que la réponse soit sous forme de chaîne, vous pouvez le faire.

String ReponseText;

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

Si vous voulez un tableau d'octets réel, faites-le (désolé, vous ne voulez pas convertir ce fichier en C #)

'Declare Array Same size as response
Dim ResponseData(webStream .Length) As Byte 
'Read all the data at once
webStream.Read(ResponseData, 0, webStream .Length)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top