WCF服务 - 是否支持使用Range: bytes支持流式传输文件?

5

我有一个能够通过WebGet返回流的WCF服务。目前它能正常工作。 但是我想实现的是支持Range头,这样只返回文件的部分内容。 这是我的代码:

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设置为范围的起始值,但是如何从文件中某个位置获取一部分是最好的方法?

我是否需要创建MemoryStream并将相关字节写入其中? 这里流式传输的文件是视频文件,因此可能非常大。

1个回答

2
你可以按照自己建议的方法进行操作。使用文件流,将位置设置为范围的开头。创建一个字节数组,长度设置为所需范围的长度。然后进行以下操作:
videoStream.Read(myByteArray, 0, myByteArray.Length)

或者,您可以将位置设置为文件流的开头,并在调用read时使用第二个参数来偏移您自己从文件流的开头开始。

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


谢谢你的回答,解释得非常好。我担心的是内存消耗,因为视频必须完全读入内存中。我正在开发的服务不会有太多用户,所以这可能不是个问题,但我想知道是否有更好的性能优化方式。 - Malyngo
1
可能值得发表第二个问题,关于您的性能问题。流对于性能非常好,然而,根据您原始帖子中显示的实现,我不认为您正在将整个流加载到内存中。只有缓冲区,就像我的建议一样。希望这可以帮助您。 - Smudge202

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接