Как лучше всего читать GetResponseStream()?

Как лучше всего прочитать ответ HTTP от GetResponseStream?

В настоящее время я использую следующий подход.

Using SReader As StreamReader = New StreamReader(HttpRes.GetResponseStream)
   SourceCode = SReader.ReadToEnd()
End Using

Я не совсем уверен, что это самый эффективный способ прочитать http-ответ.

Мне нужен вывод в виде строки, я видел статью с другим подходом, но я не совсем уверен, что он хороший. И в моих тестах этот код имел некоторые проблемы с кодировкой на разных сайтах.

Как вы читаете ответы в Интернете?


person Community    schedule 26.09.2008    source источник
comment
Ваш способ мне кажется приемлемым. IOW ничего плохого в этом нет.   -  person leppie    schedule 02.10.2008
comment
Кстати, код в informit содержит ошибки, так как один .Read() не означает, что вы прочитали весь ответ, поэтому он не работает.   -  person dr. evil    schedule 04.01.2011
comment
Хотел бы я знать ответ на это. Я пытаюсь сделать это правильно на Android, потому что моя реализация очень медленная. На Android вы даже не получаете ReadToEnd().   -  person Christian Findlay    schedule 27.11.2017


Ответы (6)


Мой простой способ сделать это со строкой. Обратите внимание на второй параметр true в конструкторе StreamReader. Это говорит ему определить кодировку по меткам порядка байтов и может помочь с проблемой кодирования, которую вы получаете.

string target = string.Empty;
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=583");

HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
try
{
  StreamReader streamReader = new StreamReader(response.GetResponseStream(),true);                
  try
  {
    target = streamReader.ReadToEnd();
  }
  finally
  {
    streamReader.Close();
  }
}
finally
{
  response.Close();
}
person Community    schedule 31.05.2010
comment
Для передачи двоичных данных (например, изображений) было бы неэффективно использовать StreamReader/string и после этого преобразовать в массив байтов? Хотите избежать изменения размера буфера при чтении из потока (по сравнению с StreamReader)? Будет ли это плохой практикой кодирования, даже для небольших переводов (‹ 1Mb). Какая будет наилучшая кодировка ответа для двоичных данных (будет ли ASCII наиболее эффективным для преобразования в массив байтов, а не, скажем, UTF-8)? Спасибо. - person samis; 06.10.2016
comment
Ответ: stackoverflow.com/questions/5867227 / - person samis; 06.10.2016

Я использую что-то вроде этого для загрузки файла с URL-адреса:

if (!Directory.Exists(localFolder))
{
    Directory.CreateDirectory(localFolder);   
}


try
{
    HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(Path.Combine(uri, filename));
    httpRequest.Method = "GET";

    // if the URI doesn't exist, an exception will be thrown here...
    using (HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse())
    {
        using (Stream responseStream = httpResponse.GetResponseStream())
        {
            using (FileStream localFileStream = 
                new FileStream(Path.Combine(localFolder, filename), FileMode.Create))
            {
                var buffer = new byte[4096];
                long totalBytesRead = 0;
                int bytesRead;

                while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    totalBytesRead += bytesRead;
                    localFileStream.Write(buffer, 0, bytesRead);
                }
            }
        }
    }
}
catch (Exception ex)
{
    // You might want to handle some specific errors : Just pass on up for now...
    // Remove this catch if you don't want to handle errors here.
    throw;
}
person Mitch Wheat    schedule 26.09.2008

Возможно, вы могли бы заглянуть в WebClient класс. Вот пример:

using System.Net;

namespace WebClientExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var remoteUri = "http://www.contoso.com/library/homepage/images/";
            var fileName = "ms-banner.gif";
            WebClient myWebClient = new WebClient();
            myWebClient.DownloadFile(remoteUri + fileName, fileName);
        }
    }
}
person Community    schedule 10.05.2009

В powershell у меня есть эта функция:

function GetWebPage
{param ($Url, $Outfile)
    $request = [System.Net.HttpWebRequest]::Create($SearchBoxBuilderURL)
    $request.AuthenticationLevel = "None"
    $request.TimeOut = 600000     #10 mins 
    $response = $request.GetResponse() #Appending "|Out-Host" anulls the variable
    Write-Host "Response Status Code: "$response.StatusCode
    Write-Host "Response Status Description: "$response.StatusDescription
    $requestStream = $response.GetResponseStream()
    $readStream = new-object System.IO.StreamReader $requestStream
    new-variable db | Out-Host
    $db = $readStream.ReadToEnd()
    $readStream.Close()
    $response.Close()
    #Create a new file and write the web output to a file
    $sw = new-object system.IO.StreamWriter($Outfile)
    $sw.writeline($db) | Out-Host
    $sw.close() | Out-Host
}

И я называю это так:

$SearchBoxBuilderURL = $SiteUrl + "nin_searchbox/DailySearchBoxBuilder.asp"
$SearchBoxBuilderOutput="D:\ecom\tmp\ss2.txt"
GetWebPage $SearchBoxBuilderURL $SearchBoxBuilderOutput
person Community    schedule 10.05.2012

Вы забыли определить "buffer" и "totalBytesRead":

using ( FileStream localFileStream = ....  
{  
    byte[] buffer = new byte[ 255 ];  
    int bytesRead;  
    double totalBytesRead = 0;  

    while ((bytesRead = .... 
person Community    schedule 02.10.2008

Столкнулся с похожей ситуацией:

Я пытался прочитать необработанный ответ в случае ошибки HTTP, использующей службу SOAP, используя BasicHTTPBinding.

Однако при чтении ответа с помощью GetResponseStream() получил ошибку:

Поток не читается

Итак, этот код работал для меня:

try
{
    response = basicHTTPBindingClient.CallOperation(request);
}
catch (ProtocolException exception)
{
    var webException = exception.InnerException as WebException;

    var alreadyClosedStream = webException.Response.GetResponseStream() as MemoryStream;
    using (var brandNewStream = new MemoryStream(alreadyClosedStream.ToArray()))
    using (var reader = new StreamReader(brandNewStream))
        rawResponse = reader.ReadToEnd();
}
person Community    schedule 15.05.2017
comment
Конечно, использование MemoryStream в сочетании с StreamReader.ReadToEnd() только для декодирования строки UTF8 из ужеClosedStream.ToArray() работает. Но и rawResponse = System.Text.Encoding.UTF8.GetString(alreadyClosedStream.ToArray()) тоже, и он намного проще и читабельнее... ;) - person ; 14.02.2018