2008-09-26 17 views
21

Jaki jest najlepszy sposób odczytywania odpowiedzi HTTP z GetResponseStream?Jaki jest najlepszy sposób odczytu GetResponseStream()?

Obecnie używam następującego podejścia.

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

Nie jestem do końca pewien, czy jest to najbardziej efektywny sposób odczytywania odpowiedzi http.

Potrzebuję wyjścia jako ciąg, widziałem article z innym podejściem, ale nie jestem całkiem, jeśli jest dobry. W moich testach ten kod miał pewne problemy z kodowaniem w różnych witrynach.

Jak czytasz odpowiedzi w Internecie?

+3

Twoja droga wydaje się ok do mnie. IOW nic z tym nie jest. – leppie

+0

Kod BTW w informit jest błędny, ponieważ jeden .Read() nie oznacza, że ​​przeczytałeś całą odpowiedź, więc to się nie uda. –

+0

Chciałbym znać odpowiedź na to pytanie. Próbuję to naprawić na Androidzie, ponieważ moja implementacja jest bardzo powolna. Na Androidzie nie masz nawet funkcji ReadToEnd(). –

Odpowiedz

15

używam czegoś takiego, aby pobrać plik z adresem 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; 
} 
3

zapomniałeś zdefiniować "bufor" i "totalBytesRead":

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

    while ((bytesRead = .... 
13

Może mógłbyś zajrzeć do WebClient klasa. Oto przykład:

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); 
     } 
    } 
} 
11

Mój prosty sposób robienia tego na sznurku. Zwróć uwagę na drugi parametr true na konstruktorze StreamReader. To oznacza, że ​​wykrywa kodowanie ze znaczników kolejności bajtów i może pomóc w rozwiązaniu problemu z kodowaniem.

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(); 
} 
+0

Do transferu danych binarnych (takich jak obrazy), byłoby nieefektywne korzystanie z StreamReader/string i konwersja do tablicy bajtowej po? Chcesz uniknąć radzenia sobie z wielkością bufora podczas czytania ze Stream (kontra StreamReader)? Czy byłoby to złe praktyki kodowania, nawet dla małych transferów (<1Mb). Jaki byłby najlepszy sposób kodowania odpowiedzi dla danych binarnych (czy ASCII byłby najskuteczniejszy do konwersji na tablicę bajtów, czy raczej UTF-8)? Dzięki. – samosaris

+0

** Odpowiedź: ** http: // stackoverflow.com/questions/5867227/convert-streamreader-byte byte – samosaris

6

PowerShell, mam tę funkcję:

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 
} 

A ja nazywam to tak:

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

mam do czynienia z podobną sytuacją:

Próbowałam odczytać nieprzetworzoną odpowiedź w przypadku błędu HTTP pobierającego usługę SOAP przy użyciu BasicHTTPBinding.

Jednak po przeczytaniu odpowiedzi korzystając GetResponseStream(), dostaje błąd:

Stream not readable

Tak, ten kod pracował dla mnie:

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(); 
} 
+0

Oczywiście, użycie obiektu MemoryStream w połączeniu z funkcją StreamReader.ReadToEnd() w celu zdekodowania ciągu znaków UTF8 z obiektu alreadyClosedStream.ToArray(). Ale tak samo robi 'rawResponse = System.Text.Encoding.UTF8.GetString (alreadyClosedStream.ToArray())' i jest o wiele prostszy i łatwiejszy do odczytania ...;) – elgonzo