How to specify range >2GB for HttpWebRequest in .NET 3.5
I'm building this class to download files in parts/sections/segments. In .NET 4.0, I can use this code to specify the range to download from
long startPos = int.MaxValue+1;
HttpWebRequest.AddRange(startPos);
and it works because there is a long overload for the AddRange method.
When I looked up the .NET 3.5 version, I realised the AddRange()
method allows using int
only.
The possible workaround would be using the AddRange(string, int)
or AddRange(string, int, int)
methods. Since the class will have to work in .NET 3.5, I'll have to go with the string specification but unfortunately I can't seem to find any sample code that shows how to specify ranges using this procedure in .NET 3.5. Can anyone show be how to do this?
Thanks.
Update
As the first code sample I wrote shows, I would like to specify a range of type long
instead of int
. Using type int
allows requesting for byte ranges only up to 2GB but long
allows requesting for byte ranges beyong 2GB.
The question therefore is: How do I specify byte ranges of 2GB or higher on HttpWebRequest
in .NET 3.开发者_开发问答5?
This is the code by Mutant_Fruit copied from WebRequest.AddRange - what about files > 2gb? showing how to to add a range specifier longer than 2GB to an HttpWebRequest.
MethodInfo method = typeof(WebHeaderCollection).GetMethod
("AddWithoutValidate", BindingFlags.Instance | BindingFlags.NonPublic);
HttpWebRequest request = (HttpWebRequest) WebRequest.Create ("http://www.example.com/file.exe");
long start = int32.MaxValue;
long end = int32.MaxValue + 100000;
string key = "Range";
string val = string.Format ("bytes={0}-{1}", start, end);
method.Invoke (request.Headers, new object[] { key, val });
I wrote this extension method for it.
#region HttpWebRequest.AddRange(long)
static MethodInfo httpWebRequestAddRangeHelper = typeof(WebHeaderCollection).GetMethod
("AddWithoutValidate", BindingFlags.Instance | BindingFlags.NonPublic);
/// <summary>
/// Adds a byte range header to a request for a specific range from the beginning or end of the requested data.
/// </summary>
/// <param name="request">The <see cref="System.Web.HttpWebRequest"/> to add the range specifier to.</param>
/// <param name="start">The starting or ending point of the range.</param>
public static void AddRange(this HttpWebRequest request, long start) { request.AddRange(start, -1L); }
/// <summary>Adds a byte range header to the request for a specified range.</summary>
/// <param name="request">The <see cref="System.Web.HttpWebRequest"/> to add the range specifier to.</param>
/// <param name="start">The position at which to start sending data.</param>
/// <param name="end">The position at which to stop sending data.</param>
public static void AddRange(this HttpWebRequest request, long start, long end)
{
if (request == null) throw new ArgumentNullException("request");
if (start < 0) throw new ArgumentOutOfRangeException("start", "Starting byte cannot be less than 0.");
if (end < start) end = -1;
string key = "Range";
string val = string.Format("bytes={0}-{1}", start, end == -1 ? "" : end.ToString());
httpWebRequestAddRangeHelper.Invoke(request.Headers, new object[] { key, val });
}
#endregion
The extension methods above need the following using
directives
using System.Reflection;
using System.Net;
And there is no need to use this this extension method in .NET 4 because there are two overloads of the AddRange
method that accept int64
(long
) as parameters.
Since .NET 4, HttpWebRequest.AddRange()
supports long:
http://msdn.microsoft.com/en-us/library/dd992108.aspx
I believe the documentation gives some insight into that:
An example of a Range header in an HTTP protocol request that requests the first 100 bytes would be would be the following:
Range: bytes=-99\r\n\r\n
For this example, the rangeSpecifier parameter would be specified as "bytes" and the range parameter would be -99.
Then there is also this from Wikipedia:
Range
Request only part of an entity. Bytes are numbered from 0.
Range: bytes=500-999
So the code that you would result on the example above is
HttpWebRequest.AddRange("bytes", 500, 999);
If I understand you correctly, you do not have enough int and long. But operator overloading only int?
Use headers.
httpWebRequest.Headers.Add("Range", "bytes=500-999");
精彩评论