C # загрузка веб-страницы. Требуется лучший способ, высокая загрузка ЦП - PullRequest
2 голосов
/ 22 октября 2008

Я пытаюсь заставить этот кусок кода работать немного лучше. Я подозреваю, что это цикл чтения одного байта за раз. Я не мог найти другой способ сделать это с распаковкой gzip. Реализация StreamReader - это нормально, но она возвращает строку, которую я не могу передать потоку распаковки.

Есть ли лучший способ?

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();

Ответы [ 3 ]

9 голосов
/ 22 октября 2008

Я согласен с jmcd, что WebClient будет намного проще, в частности, WebClient.DownloadData.

Реальный вопрос, проблема в том, что вы читаете отдельные байты, когда у вас, вероятно, должен быть фиксированный буфер, и цикл - т.е. 1003 *

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

[редактировать, чтобы добавить акцент] Важным моментом является то, что вы только обрабатывает каждый раз ценность данных "bytesRead"; все остальное там - мусор.

1 голос
/ 22 октября 2008

Является ли класс WebClient бесполезным для того, что вы хотите сделать?

0 голосов
/ 22 октября 2008

Если вы хотите получить ответ в виде строки, вы можете сделать это.

String ReponseText;

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

Если вы хотите, чтобы действительный байтовый массив делал это (извините, не хочется переходить на 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)
...