C # scaricando una pagina Web. È necessario un modo migliore, elevato utilizzo della CPU

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

  •  03-07-2019
  •  | 
  •  

Domanda

Sto cercando di far funzionare un po 'meglio questo pezzo di codice. Ho il sospetto che sia il ciclo che legge un byte alla volta. Non sono riuscito a trovare un altro modo di farlo con la decompressione gzip. L'implementazione di un StreamReader va bene, ma restituisce una stringa che non posso trasmettere al flusso di decompressione.

C'è un modo migliore?

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();
È stato utile?

Soluzione

Concordo con jmcd sul fatto che WebClient sarebbe molto più semplice, in particolare WebClient.DownloadData.

per quanto riguarda la vera domanda, il problema è che stai leggendo singoli byte, quando probabilmente dovresti avere un buffer fisso, e loop - cioè

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

[modifica per aggiungere enfasi] Il bit importante è che solo elabori " bytesLeggi " valore dei dati ogni volta; tutto ciò che c'è oltre è spazzatura.

Altri suggerimenti

WebClient classe inutile per quello che vuoi fare?

Se vuoi la risposta come stringa puoi farlo.

String ReponseText;

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

Se vuoi un vero array di byte, fai questo (scusa, non mi va di convertirlo in C # per questo)

'Declare Array Same size as response
Dim ResponseData(webStream .Length) As Byte 
'Read all the data at once
webStream.Read(ResponseData, 0, webStream .Length)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top