2011-05-06 11 views
5

Tengo un servicio WCF que puede devolver una secuencia a través de un WebGet. Esto está funcionando bien hasta ahora. Pero lo que me gustaría implementar es el soporte para el encabezado del rango, de modo que solo se devuelvan partes del archivo. Este es mi código hasta aquí:WCF service - soporte para streaming de archivos con Rango: bytes de soporte?

public System.IO.Stream GetStream(string mElementID) 
{ 
     // build the filePath 
     FileInfo file = GetFile(mElementID); 
     try 
     { 
      FileStream videoStream = File.OpenRead(file.FullName); 

      if (request.Headers.AllKeys.Contains("Range")) 
      { 
       long startRange = ...; // get the start range from the header 
       long endRange = ...; // get the end range from the header 
       videoStream.Position = startRange; 
       // how can I set the end of the range? 
       //TODO: Don't forget to add the Content-Range header to the response! 
      } 

      WebOperationContext.Current.OutgoingResponse.ContentType = GetMimeType(file); 
      WebOperationContext.Current.OutgoingResponse.Headers.Add("Accept-Ranges", "bytes"); 
      return videoStream; 
     } 
     catch (FileNotFoundException){} 
     catch (IOException ex) 
     { 
      throw ex; 
     } 
     // throw a 404 
     throw new WebFaultException(System.Net.HttpStatusCode.NotFound); 
} 

acabo de crear un FileStream, y regresar eso. Ahora me pregunto cuál es la mejor forma de obtener un rango de ese Stream.

creo que podría establecer videoStream.Position al valor inicial de la gama, pero ¿cuál es la mejor manera de obtener una parte de somwehere en el archivo a algún lugar en el archivo?

¿Tengo que crear un MemoryStream y escribir los bytes relevantes en eso? Los archivos que se transmiten aquí son archivos de video, por lo que pueden ser bastante grandes.

Respuesta

2

Puede hacer lo que haya sugerido usted mismo. Con filestream, establece la posición al inicio del rango. Cree una matriz de bytes establecida en la longitud del rango que desee. Luego hacer

videoStream.Read(myByteArray, 0, myByteArray.Length) 

Como alternativa, se puede establecer la posición del comienzo de la filestream, y usar el segundo parámetro cuando se llama a sí mismo para compensar leer desde el principio de la filestream.

Una vez que haya leído en el búfer (matriz de bytes) puede colocarlo en una nueva secuencia de memoria (que tiene un constructor sobrecargado que acepta una matriz de bytes). A continuación, puede devolver el memoryStream derivado.

+0

Gracias por su respuesta, muy bien explicada. Lo que me preocupa es el consumo de memoria, ya que el video debe leerse completamente en la memoria. El servicio en el que estoy trabajando no tendrá muchos usuarios, por lo que probablemente no sea un problema, pero me pregunto si podría haber una manera mejor, en cuanto al rendimiento. – Malyngo

+1

Puede valer la pena publicar una segunda pregunta con respecto a sus inquietudes sobre el rendimiento. Sin embargo, las transmisiones son muy buenas para el rendimiento, y con la implementación que se muestra en su publicación original, no creo que esté cargando toda la secuencia en la memoria. Solo el buffer como mi sugerencia. Espero que ayude. – Smudge202