Как лучше всего прочитать HTTP-ответ от GetResponseStream?
Сейчас я использую следующий подход.
Using SReader As StreamReader = New StreamReader(HttpRes.GetResponseStream)
SourceCode = SReader.ReadToEnd()
End Using
Я не совсем уверен, что это наиболее эффективный способ чтения HTTP-ответа.
Мне нужен вывод в виде строки, я видел статья с другим подходом, но я не совсем понимаю, хороший ли он. И в моих тестах этот код имел некоторые проблемы с кодировкой на разных веб-сайтах.
Как вы читаете веб-ответы?
Кстати, код в informit ошибочен как один .Read () не означает, что вы прочитали весь ответ, поэтому он не удастся.
Хотел бы я знать ответ на это. Я пытаюсь сделать это правильно на Android, потому что моя реализация очень медленная. На Android у вас даже нет ReadToEnd ().





Я использую что-то вроде этого, чтобы загрузить файл с 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;
}
Вы забыли определить буфер и totalBytesRead:
using ( FileStream localFileStream = ....
{
byte[] buffer = new byte[ 255 ];
int bytesRead;
double totalBytesRead = 0;
while ((bytesRead = ....
Может быть, вы могли бы изучить класс 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);
}
}
}
Мой простой способ сделать это со строкой. Обратите внимание на второй параметр 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();
}
Для передачи двоичных данных (например, изображений) было бы неэффективно использовать StreamReader / string и преобразовывать в байтовый массив после? Хотите избежать изменения размера буфера при чтении из Stream (по сравнению с StreamReader)? Будет ли это плохой практикой кодирования даже для небольших переводов (<1 МБ). Какая будет наилучшая кодировка ответа для двоичных данных (будет ли ASCII наиболее эффективным для преобразования в массив байтов, а не UTF-8)? Спасибо.
В 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
Я столкнулся с похожей ситуацией:
Я пытался прочитать необработанный ответ в случае ошибки HTTP, использующей службу SOAP, используя BasicHTTPBinding.
Однако при чтении ответа с помощью GetResponseStream() возникла ошибка:
Stream not readable
Итак, у меня сработал этот код:
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 () только для декодирования строки UTF8 из ужеClosedStream.ToArray () работает. Но как и rawResponse = System.Text.Encoding.UTF8.GetString(alreadyClosedStream.ToArray()), он намного проще и легче читается ...;)
Мне твой путь кажется нормальным. В этом нет ничего плохого.