2010-08-08 30 views
35

Estoy tratando de obtener una imagen de una url usando una secuencia byte. Pero me sale este mensaje de error:Error "Esta secuencia no admite las operaciones de búsqueda" en C#

Esta secuencia no es compatible con las operaciones de búsqueda.

Este es mi código:

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; 

¿Qué estoy haciendo tipos equivocados?

+0

Una situación similar fue respondida y puede obtener ayuda, consulte: http://stackoverflow.com/a/43981770/2791237 –

Respuesta

63

Probablemente desee algo como esto. O bien, la comprobación de la longitud falla, o el BinaryReader está haciendo búsquedas detrás de las escenas.

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

edición:

he comprobado usando el reflector, y es la llamada a stream.Length que falla. GetResponseStream devuelve un ConnectStream y la propiedad Length de esa clase arroja la excepción que vio. Como se menciona en otros carteles, no se puede obtener de manera confiable la longitud de una respuesta HTTP, por lo que tiene sentido.

+0

¡Hola, ngoozeff, gracias, eso fue lo que hizo! Parece estar funcionando! – Yustme

+5

La longitud del flujo falla pero el response.ContentLength devuelve una longitud válida. – andleer

+0

No necesita obtenerlo en bytes como este, sin embargo, para una imagen, si desea usarla como imagen. Ver mi respuesta, a continuación. – vapcguy

0

La longitud de una secuencia no se puede leer de la secuencia ya que el receptor no sabe cuántos bytes enviará el remitente. Intente colocar un protocolo sobre http y enviar, es decir, la longitud como primer elemento de la secuencia.

5

Si el servidor no envía una especificación de longitud en el encabezado HTTP, el tamaño de la secuencia es desconocido, por lo que se obtiene el error cuando se intenta utilizar la propiedad Length.

Lea la secuencia en trozos más pequeños, hasta que llegue al final de la secuencia.

6

No se puede pedir confiablemente una conexión HTTP para su longitud. Es posible hacer que el servidor le envíe la longitud por adelantado, pero (a) ese encabezado a menudo falta y (b) no está garantizado que sea correcto.

su lugar debe:

  1. Crear una longitud fija byte[] que se pasa al método Stream.Read
  2. Crear una List<byte>
  3. Después de cada lectura, llame List.AddRange para anexar el contenido de su fijo búfer de longitud en su lista de bytes

Tenga en cuenta que la última llamada al Read devolverá menos que el número completo de bytes que solicitó. Asegúrese de agregar solo esa cantidad de bytes en su List<byte> y no en el total byte[], o obtendrá basura al final de su lista.

+0

Hola, estoy un poco confundido ahora. ¿Cómo debería ser mi código entonces? – Yustme

+0

@Yustme, 'var buffer = new List (); while (true) {byte [] tmpBuffer = nuevo byte [1024]; int bytesRead = br.Read (tmpBuffer, 0, tmpBuffer.length); buffer.AddRange (tmpBuffer.Take (bytesRead)); if (bytesRead strager

+0

O use un StreamReader – Justin

10

Utilice un StreamReader lugar:

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

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

(Nota - los rendimientos por encima de un String en lugar de una matriz de bytes)

+1

(... que luego se puede convertir en una matriz de bytes utilizando funciones proporcionadas por las clases de codificación.) – sunside

+0

esta debería ser la respuesta aceptada, es mucho más conveniente que la otra ¡uno! – Couitchy

+0

Si tuviera las rutinas o el enlace sobre cómo obtenerlo desde un StreamReader en bytes, o una imagen. Sin eso, todavía estamos en la primera casilla, diría yo. Esto no me ayudó para nada. – vapcguy

0

Con imágenes, no es necesario leer el número de bytes en absoluto .Sólo hacer esto:

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 
} 
Cuestiones relacionadas