Ошибка «Этот поток не поддерживает операции поиска» в C # - PullRequest
44 голосов
/ 08 августа 2010

Я пытаюсь получить изображение из URL, используя поток byte.Но я получаю сообщение об ошибке:

Этот поток не поддерживает операции поиска.

Это мой код:

byte[] b;
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
WebResponse myResp = myReq.GetResponse();

Stream stream = myResp.GetResponseStream();
int i;
using (BinaryReader br = new BinaryReader(stream))
{
    i = (int)(stream.Length);
    b = br.ReadBytes(i); // (500000);
}
myResp.Close();
return b;

не так, ребята?

Ответы [ 7 ]

69 голосов
/ 08 августа 2010

Вы, вероятно, хотите что-то подобное.Либо проверка длины не удалась, либо BinaryReader выполняет поиск за кулисами.

HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
WebResponse myResp = myReq.GetResponse();

byte[] b = null;
using( Stream stream = myResp.GetResponseStream() )
using( MemoryStream ms = new MemoryStream() )
{
  int count = 0;
  do
  {
    byte[] buf = new byte[1024];
    count = stream.Read(buf, 0, 1024);
    ms.Write(buf, 0, count);
  } while(stream.CanRead && count > 0);
  b = ms.ToArray();
}

edit:

Я проверил с помощью отражателя, и это - вызов потока.GetResponseStream возвращает ConnectStream, а свойство Length этого класса выдает исключение, которое вы видели.Как упоминалось в других постерах, вы не можете надежно получить длину ответа HTTP, так что это имеет смысл.

12 голосов
/ 08 августа 2010

Вместо этого используйте StreamReader :

HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
WebResponse myResp = myReq.GetResponse();

StreamReader reader = new StreamReader(myResp.GetResponseStream());
return reader.ReadToEnd();

(Примечание. Выше приведено String вместо байтового массива)

7 голосов
/ 08 августа 2010

Вы не можете достоверно запросить HTTP-соединение для его длины.Можно заставить сервер отправлять вам длину заранее, но (а) этот заголовок часто отсутствует и (б) он не гарантированно будет правильным.

Вместо этого вам следует:

  1. Создайте byte[] фиксированной длины, который вы передаете методу Stream.Read
  2. Создайте List<byte>
  3. После каждого чтения вызывайте List.AddRange, чтобы добавить содержимоеваш буфер фиксированной длины в вашем списке байтов

Обратите внимание, что последний вызов Read вернет меньше, чем полное количество байтов, которое вы запросили.Убедитесь, что вы добавляете только это количество байтов к своему List<byte>, а не ко всему byte[], иначе вы получите мусор в конце списка.

5 голосов
/ 08 августа 2010

Если сервер не отправляет спецификацию длины в заголовке HTTP, размер потока неизвестен, поэтому вы получаете сообщение об ошибке при попытке использовать свойство Length.

Чтение потока в меньшем размерекуски, пока не дойдете до конца потока.

0 голосов
/ 09 января 2019

Возможно, вам следует использовать System.Net.WebClient API.Если вы уже используете client.OpenRead(url), используйте client.DownloadData (url)

var client = new System.Net.WebClient();
byte[] buffer = client.DownloadData(url);
using (var stream = new MemoryStream(buffer))
{
    ... your code using the stream ...
}

Очевидно, что все файлы загружаются до создания Stream, так что это может победить цель использования Stream.webClient.DownloadData("https://your.url") получает байтовый массив, который затем можно превратить в MemoryStream.

0 голосов
/ 08 ноября 2014

С изображениями вам вообще не нужно считывать количество байтов. Просто сделай это:

Image img = null;
string path = "http://www.example.com/image.jpg";
WebRequest request = WebRequest.Create(path);
req.Credentials = CredentialCache.DefaultCredentials; // in case your URL has Windows auth
WebResponse resp = req.GetResponse();

using( Stream stream = response.GetResponseStream() ) 
{
    img = Image.FromStream(stream);
    // then use the image
}
0 голосов
/ 08 августа 2010

Длина потока не может быть прочитана из потока, так как получатель не знает, сколько байтов отправит отправитель. Попробуйте поместить протокол поверх http и отправить длину в качестве первого элемента в потоке.

...