2008-09-26 30 views
21

¿Cuál es la mejor manera de leer una respuesta HTTP de GetResponseStream?¿Cuál es la mejor manera de leer GetResponseStream()?

Actualmente estoy utilizando el siguiente enfoque.

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

No estoy muy seguro de si esta es la forma más eficiente de leer una respuesta http.

Necesito la salida como hilo, he visto un article con un enfoque diferente, pero no estoy del todo bien si es bueno. Y en mis pruebas, ese código tenía algunos problemas de codificación en diferentes sitios web.

¿Cómo lees las respuestas web?

+3

Su forma parece que está bien para mí. IOW nada de malo en eso. – leppie

+0

El código BTW en información tiene errores ya que uno .Read() no significa que ha leído toda la respuesta, por lo tanto, fallará. –

+0

Ojalá supiera la respuesta a esto. Estoy tratando de hacer esto bien en Android porque mi implementación es extremadamente lenta. En Android, ni siquiera obtienes ReadToEnd(). –

Respuesta

15

utilizo algo como esto para descargar un archivo desde una 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

Se le olvidó para definir "buffer" y "totalBytesRead":

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

    while ((bytesRead = .... 
13

Tal vez usted podría mirar en el WebClient clase. Aquí hay un ejemplo:

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

Mi forma simple de hacerlo con una cuerda. Tenga en cuenta el segundo parámetro true en el constructor StreamReader. Esto le indica que detecte la codificación de las marcas de orden de bytes y también puede ayudar con el problema de codificación que está recibiendo.

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

Para transferir datos binarios (como imágenes), ¿sería ineficiente usar StreamReader/string y convertir a una matriz de bytes después? ¿Desea evitar el cambio de tamaño del búfer al leer desde un Stream (frente a StreamReader)? ¿Esta sería una mala práctica de codificación, incluso para transferencias pequeñas (<1Mb)? ¿Cuál sería la mejor codificación de respuesta para datos binarios (sería ASCII el más eficiente para convertir a una matriz de bytes, frente a decir UTF-8)? Gracias. – samosaris

+0

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

6

En PowerShell, tengo esta función:

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 
} 

Y lo llamo así:

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

me enfrentaba a una situación similar:

yo estaba tratando de lea la respuesta sin procesar en caso de un error HTTP que consuma un servicio SOAP, utilizando BasicHTTPBinding.

Sin embargo, al leer la respuesta utilizando GetResponseStream(), tiene el error:

Stream not readable

Por lo tanto, el código que funcionó para mí:

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

Seguro, el uso de un MemoryStream junto con StreamReader.ReadToEnd() solo para decodificar la cadena UTF8 de alreadyClosedStream.ToArray() funciona. Pero también lo hace 'rawResponse = System.Text.Encoding.UTF8.GetString (alreadyClosedStream.ToArray())', y es mucho más simple y fácil de leer ...;) – elgonzo

Cuestiones relacionadas