2008-09-26 10 views
21

Quelle est la meilleure façon de lire une réponse HTTP de GetResponseStream?Quelle est la meilleure façon de lire GetResponseStream()?

Actuellement j'utilise l'approche suivante. Je ne suis pas sûr si c'est le moyen le plus efficace de lire une réponse http.

J'ai besoin de la sortie en tant que chaîne, j'ai vu un article avec une approche différente, mais je ne suis pas tout à fait si c'est un bon. Et dans mes tests, ce code a eu des problèmes d'encodage sur différents sites Web.

Comment lisez-vous les réponses Web?

+3

Votre me semble ok à. IOW rien de mal avec ça. – leppie

+0

Le code BTW dans informit est buggé comme un. Read() ne signifie pas que vous avez lu toute la réponse, donc il va échouer. –

+0

Je voudrais savoir la réponse à cette question. J'essaie d'obtenir ce droit sur Android parce que ma mise en œuvre est extrêmement lente. Sur Android, vous n'avez même pas ReadToEnd(). –

Répondre

15

J'utilise quelque chose comme ça pour télécharger un fichier à partir d'une 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

Vous avez oublié de définir « tampon » et « totalBytesRead »:

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

    while ((bytesRead = .... 
13

Peut-être que vous pourriez regarder dans le WebClient classe. Voici un exemple:

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

Ma façon simple de le faire à une chaîne. Notez le deuxième paramètre true sur le constructeur StreamReader. Cela lui indique de détecter le codage à partir des marques d'ordre des octets et peut aider avec le problème d'encodage que vous obtenez également.

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

Pour transférer des données binaires (comme des images), serait-il inefficace d'utiliser StreamReader/string et de convertir en un tableau d'octets après? Vous voulez éviter d'avoir à gérer le redimensionnement du tampon lors de la lecture d'un Stream (vs StreamReader)? Serait-ce une mauvaise pratique de codage, même pour les petits transferts (<1Mb). Quel serait le meilleur codage de réponse pour les données binaires (ASCII serait-il le plus efficace pour convertir en un tableau d'octets, par rapport à UTF-8)? Merci. – samosaris

+0

** Réponse: ** http: // stackoverflow.com/questions/5867227/convert-streamreader-to-byte – samosaris

6

En Powershell, j'ai cette fonction:

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 
} 

Et je l'appelle comme ceci:

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

je faisais face à une situation similaire:

Je tentais de lire la réponse brute en cas d'erreur HTTP consommant un service SOAP, en utilisant BasicHTTPBinding.

Cependant, lors de la lecture de la réponse à l'aide GetResponseStream(), a obtenu l'erreur:

Stream not readable

Ainsi, ce code a fonctionné pour moi:

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

Bien sûr, en utilisant un MemoryStream en conjonction avec StreamReader.ReadToEnd() juste pour décoder la chaîne UTF8 à partir de alreadyClosedStream.ToArray() fonctionne. Mais aussi rawResponse = System.Text.Encoding.UTF8.GetString (alreadyClosedStream.ToArray()) ', et c'est beaucoup plus simple et plus facile à lire ...;) – elgonzo

Questions connexes