阅读 GetResponseStream() 的最佳方法是啥?

Posted

技术标签:

【中文标题】阅读 GetResponseStream() 的最佳方法是啥?【英文标题】:What is the best way to read GetResponseStream()?阅读 GetResponseStream() 的最佳方法是什么? 【发布时间】:2010-09-13 07:56:01 【问题描述】:

从 GetResponseStream 读取 HTTP 响应的最佳方法是什么?

目前我正在使用以下方法。

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

我不太确定这是否是读取 http 响应的最有效方式。

我需要将输出作为字符串,我见过article 采用不同的方法,但我不太确定它是否是一个好的方法。在我的测试中,这些代码在不同的网站上存在一些编码问题。

您如何阅读网络回复?

【问题讨论】:

你的方式对我来说似乎没问题。 IOW 没有错。 informit 中的 BTW 代码是错误的,因为 .Read() 并不意味着您已经阅读了所有响应,因此它会失败。 我希望我知道这个问题的答案。我试图在 android 上做到这一点,因为我的实现非常慢。在 Android 上,您甚至不会得到 ReadToEnd()。 【参考方案1】:

我也遇到过类似的情况:

我尝试使用 BasicHTTPBinding 读取原始响应以防使用 SOAP 服务的 HTTP 错误。

但是,当使用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();

【讨论】:

当然,将 MemoryStream 与 StreamReader.ReadToEnd() 结合使用只是为了解码来自 alreadyClosedStream.ToArray() 的 UTF8 字符串。但rawResponse = System.Text.Encoding.UTF8.GetString(alreadyClosedStream.ToArray()) 也是如此,而且它更简单、更易于阅读...... ;)【参考方案2】:

我使用这样的东西从 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】:

在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

【讨论】:

【参考方案4】:

我对字符串执行此操作的简单方法。请注意 StreamReader 构造函数上的 true 第二个参数。这告诉它从字节顺序标记中检测编码,并且可能有助于解决您遇到的编码问题。

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();

【讨论】:

对于传输二进制数据(如图片),使用StreamReader/string后转换为字节数组会不会效率低下?想要在从 Stream(与 StreamReader)读取时避免处理缓冲区大小调整?即使对于小传输( 答案: ***.com/questions/5867227/…【参考方案5】:

也许您可以查看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);
        
    

【讨论】:

【参考方案6】:

你忘了定义“buffer”和“totalBytesRead”:

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

    while ((bytesRead = .... 

【讨论】:

以上是关于阅读 GetResponseStream() 的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

从南国飞往泰国的最短路径你造吗?

每个程序员都应该阅读的最有影响力的书是什么?

如何找到解决所有 N 个问题所需的最短时间?

这可能是把Docker的概念讲的最清楚的一篇文章

获取公网IP

文件流生成文件