2011-05-06 147 views
5

我有一个WCF服务,可以通过WebGet返回一个流。这工作很好。 但是我想实现的是对Range头的支持,所以只返回文件的一部分。 这是我的代码这一步:WCF服务 - 支持范围:字节支持流文件?

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

我只是创建一个FileStream,并返回。现在我想知道什么是获得该流的范围的最佳方式。

我想我可以设置videoStream.Position该范围的初始值,但什么是文件地方在文件中从 somwehere得到部分的最佳方式?

我是否必须创建一个MemoryStream并将相关字节写入该字段? 这里流式传输的文件是视频文件,因此可能相当大。

回答

2

你可以照你自己的建议去做。使用文件流,将位置设置为范围的起始位置。创建一个设置为所需范围长度的字节数组。然后做

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

或者,你可以设置位置到FILESTREAM的开始,并使用第二个参数时,调用read从FILESTREAM开始偏移自己。

一旦你读入缓冲区(字节数组),你可以把它放入一个新的内存流(它有一个接受一个字节数组的重载构造函数)。然后你可以返回派生的memoryStream。

+0

谢谢你的回答,很好解释。我担心的是内存消耗,因为视频必须完全读入内存。我正在使用的服务不会有很多用户,所以这可能不会成为问题,但我想知道是否有更好的方法,性能明智。 – Malyngo 2011-05-09 07:19:26

+1

关于您的表现问题,可能值得发布第二个问题。流对于性能来说是非常好的,但是在原始文章中显示的实现中,我不相信你正在将整个流加载到内存中。根据我的建议只有缓冲区。希望有所帮助。 – Smudge202 2011-05-09 09:22:16