Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF service - support for streaming files with Range: bytes support?

Tags:

c#

.net

http

wcf

I have a WCF service that can return a stream via a WebGet. This is working fine as far. But what I would like to implement is support for the Range header, so that only parts of the file are returned. This is my code this far:

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

I just create a FileStream, and return that. Now I wonder what is the best way to get a range of that Stream.

I think I could set videoStream.Position to the start value of the Range, but what is the best way to get a part from somwehere in the file to somewhere in the file?

Do I have to create a MemoryStream and write the relevant bytes into that? The files that are streamed here are video files, so can be quite big.

like image 773
Malyngo Avatar asked Nov 04 '22 22:11

Malyngo


1 Answers

You can do as you've suggested yourself. With the filestream, set the position to the start of the range. Create a byte array set to the length of the range you want. Then do

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

Alternatively, you can set the position to the start of the filestream, and use the second parameter when calling read to offset yourself from the beginning of the fileStream.

Once you've read into the buffer (byte array) you can place it into a new memory stream (which has an overloaded constructor that accepts a byte array). You can then return the derived memoryStream.

like image 155
Smudge202 Avatar answered Nov 10 '22 15:11

Smudge202