C# загрузка веб-страницы. Нужен лучший способ, высокая загрузка ЦП

Я пытаюсь заставить этот фрагмент кода работать немного лучше. Я подозреваю, что это цикл, читающий по одному байту за раз. Я не мог найти другого способа сделать это с помощью распаковки 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();
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 806
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

WebClient в порядке, если я не использую сжатие. Это похоже на то, что, возможно, придется

Razor 22.10.2008 17:00

WebClient не поддерживает распаковку :(

Razor 22.10.2008 17:10

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

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)

Разве он не говорил, что у него проблемы с использованием строки Streamreader?

NotJarvis 22.10.2008 16:59
Ответ принят как подходящий

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

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

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

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

Хороший ответ. Вероятно, это причина медлительности.

samjudson 22.10.2008 17:03

DownloadDataAsync также может подойти.

Jon Grant 22.10.2008 17:21

Другие вопросы по теме