Я пытаюсь заставить этот фрагмент кода работать немного лучше. Я подозреваю, что это цикл, читающий по одному байту за раз. Я не мог найти другого способа сделать это с помощью распаковки 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();
Класс WebClient бесполезен для того, что вы хотите делать?
WebClient не поддерживает распаковку :(
Если вам нужен ответ в виде строки, вы можете это сделать.
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?
Я согласен с 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" данных; все, что дальше, - мусор.
Хороший ответ. Вероятно, это причина медлительности.
DownloadDataAsync также может подойти.
WebClient в порядке, если я не использую сжатие. Это похоже на то, что, возможно, придется