Я пытаюсь дважды прочитать поток ответов Http следующим образом:
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
stream = response.GetResponseStream();
RssReader reader = new RssReader(stream);
do
{
element = reader.Read();
if (element is RssChannel)
{
feed.Channels.Add((RssChannel)element);
}
} while (element != null);
StreamReader sr = new StreamReader(stream);
feed._FeedRawData = sr.ReadToEnd();
Однако при выполнении кода StreamReader данные не возвращаются, потому что поток уже достиг конца. Я попытался сбросить поток через stream.Position = 0, но это вызывает исключение (я думаю, потому что поток не может изменить свою позицию вручную).
В принципе, я хотел бы проанализировать поток на предмет XML и получить доступ к необработанным данным (в строковом формате).
Есть идеи?





вы пробовали сбросить позицию потока? если это не сработает, вы можете скопировать поток в MemoryStream, и там вы можете сбрасывать позицию (то есть до 0) так часто, как захотите.
Сначала скопируйте его в новый MemoryStream. Затем вы можете перечитывать MemoryStream сколько угодно раз:
Stream responseStream = CopyAndClose(resp.GetResponseStream());
// Do something with the stream
responseStream.Position = 0;
// Do something with the stream again
private static Stream CopyAndClose(Stream inputStream)
{
const int readSize = 256;
byte[] buffer = new byte[readSize];
MemoryStream ms = new MemoryStream();
int count = inputStream.Read(buffer, 0, readSize);
while (count > 0)
{
ms.Write(buffer, 0, count);
count = inputStream.Read(buffer, 0, readSize);
}
ms.Position = 0;
inputStream.Close();
return ms;
}
Еще один комментарий - вышесказанное никогда не закрывает входящий поток. Возможно, стоит создать метод «CopyAndClose», который делает закрывает поток, чтобы вы могли сохранить простой синтаксис вызова.
Вау, приближаясь к своим героям ... Сейчас я читаю вашу книгу, мистер Скит :-) То, что вы предложили закрыть (и сообщить с помощью имени метода), в точности то, что я думал о приведенном выше коде.
.net 4 и выше имеют более короткий способ копирования потоков: Скопировать в
Копирование потока в MemoryStream, как предлагает Иэн, является правильным подходом. Но с тех пор .NET Framework 4 (выпущен в 2010 г.) у нас есть Stream.CopyTo. Пример из документов:
// Create the streams.
MemoryStream destination = new MemoryStream();
using (FileStream source = File.Open(@"c:\temp\data.dat",
FileMode.Open))
{
Console.WriteLine("Source length: {0}", source.Length.ToString());
// Copy source to destination.
source.CopyTo(destination);
}
Console.WriteLine("Destination length: {0}", destination.Length.ToString());
После этого вы можете читать destination сколько угодно раз:
// re-set to beginning and convert stream to string
destination.Position = 0;
StreamReader streamReader = new StreamReader(destination);
string text = streamReader.ReadToEnd();
// re-set to beginning and read again
destination.Position = 0;
RssReader cssReader = new RssReader(destination);
(Я видел Комментарий Энди, но поскольку это подходящий текущий ответ, у него должна быть собственная запись ответа.)
Одно крошечное предложение здесь - я часто вижу вызовы Seek, где свойство Position было бы проще и читабельнее, например ms.Position = 0; Просто мысль о будущем коде.