Как считать ответный поток, прежде чем ответ Http завершится

При создании использования запроса объектом HttpWebRequest я должен назвать метод GetResponse (), чтобы отправить запрос и вернуть ответ.
Проблема с этим методом состоит в том, что он не возвращает объект ответа, пока все данные не были получены. Скажите, что я загружаю файл на 100 МБ, я не смогу считать его, пока конец ответа и все 100 МБ не будет загружен.
То, что я хочу, должно смочь считать байты ответного потока, как только они прибывают, не ожидая ответа для завершения.
Я знаю, что могу использовать Диапазон заголовок Http, но он не будет работать над моей ситуацией.

6
задан 15 May 2010 в 22:29
поделиться

3 ответа

Я думаю, это очень близко к тому, что предлагает @Zachary. И это (кажется) работает (работает); на самом деле я думаю, что использование using, как делает @Zachary, даже "приятнее".
GetResponse(), которое вы (похоже) описали.

Кроме того, следующий код только приблизительно показывает, как все работает; он не будет читать поток до конца, например (если только по совпадению :)). Но он должен работать, если вы скопируете и вставите его в пустой проект "Console Application" в Visual Studio.

Вы можете попробовать использовать какой-нибудь "более короткий" URL для теста. В примере здесь начинается загрузка ISO дистрибутива debian (чуть больше 600 МБайт). Извините, debian, я не хотел красть вашу пропускную способность. -> Btw: есть ли что-то разумное, что можно использовать для тестирования такого сценария?

Код сильно вдохновлен C# - Как читать непрерывный поток XML по HTTP.

namespace StreamReadWebRequest
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net;
    using System.IO;

    class Program
    {
        static void Main(string[] args)
        {
            HttpWebRequest req;
            HttpWebResponse res = null;

            try
            {
                req = (HttpWebRequest)WebRequest.Create(
                        "http://cdimage.debian.org/debian-cd/5.0.4/i386/iso-cd/debian-504-i386-CD-1.iso");
                res = (HttpWebResponse)req.GetResponse();
                Stream stream = res.GetResponseStream();

                byte[] data = new byte[4096];
                int read;
                while ((read = stream.Read(data, 0, data.Length)) > 0)
                {
                    Process(data, read);
                }
            }
            finally
            {
                if (res != null)
                    res.Close();
            }
            Console.In.Read();
        }

        private static void Process(byte[] data, int read)
        {
            Console.Out.Write(ASCIIEncoding.ASCII.GetString(data));
        }
    }
}
8
ответ дан 9 December 2019 в 20:40
поделиться

Если вы установите размер буфера при чтении, вы можете читать данные по частям ... пример ...

 // Get the response stream
 using(Stream resStream = response.GetResponseStream())
 {

        string parseString = null;
        int    count      = 0;

        do
        {
            // Read a chunk of data
            count = resStream.Read(buf, 0, buf.Length);

            if (count != 0)
            {
                // Convert to ASCII
                parseString = Encoding.ASCII.GetString(buf, 0, count);

                // Append string to results
                sb.Append(tempString);
            }
        }
        while (count > 0);

}
1
ответ дан 9 December 2019 в 20:40
поделиться

Я не уверен, что у вас на стороне, но я точно знаю (и уверен, что многие люди здесь согласятся), что GetResponse () НЕ загрузит весь файл обратно. Он отправит запрос, дождется ответа и получит заголовки ответа.

После получения ответа вы можете легко получить поток ответа с помощью GetResponseStream () , который представляет собой фактический поток данных, загружаемый с сервера.И вы можете легко получить доступ к потоку ответов ДО того, как будет загружен весь файл. Это 100% правда и проверено.

Если вы не получаете такое же поведение (что действительно странно и не должно происходить), можете ли вы добавить пример кода, который не работает, как я объяснил выше?

Также проверьте пример, опубликованный Scherand . Это лишний раз доказывает, что все работает нормально, без особых хитростей.

0
ответ дан 9 December 2019 в 20:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: