使用WebClient C#实现HTTP Range: bytes

3

我正在尝试恢复文件下载。

我使用以下代码成功地下载了所需的文件。

    downlaodfile = new WebClient();
  // downlaodfile.Headers.Add("Range", "bytes=0-600000");
downlaodfile.DownloadFileAsync(new Uri(video.DownloadUrl), @"C:\Videofile.pm4");

当我取消下面的行的注释时,问题开始了,我下载了0字节。
 downlaodfile.Headers.Add("Range", "bytes=0-600000");

使用WebClient类恢复的正确方式是什么?

请注意,服务器还必须支持恢复下载。 - Icepickle
1个回答

7

你的代码无法工作,因为你不能以你尝试的方式设置范围标头。为了验证这一点,只需订阅DownloadFileCompleted事件并转储错误即可:

downlaodfile.DownloadFileCompleted += (sender, e) =>
{
    Console.WriteLine(e.Error);
};

您将得到以下打印内容:
System.Net.WebException: An exception occurred during a WebClient request. ---> System.ArgumentException: The 'Range' header must be modified using the appropriate property or method.
Parameter name: name
   at System.Net.WebHeaderCollection.ThrowOnRestrictedHeader(String headerName)
   at System.Net.WebHeaderCollection.Add(String name, String value)
   at System.Net.HttpWebRequest.set_Headers(WebHeaderCollection value)
   at System.Net.WebClient.CopyHeadersTo(WebRequest request)
   at System.Net.WebClient.GetWebRequest(Uri address)
   at System.Net.WebClient.DownloadFileAsync(Uri address, String fileName, Object userToken)
   --- End of inner exception stack trace ---

好的,那么您可能需要一个自定义WebClient:

public class WebClientEx : WebClient
{
    private readonly long from;
    private readonly long to;

    public WebClientEx(long from, long to)
    {
        this.from = from;
        this.to = to;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        var request = (HttpWebRequest)base.GetWebRequest(address);
        request.AddRange(this.from, this.to);
        return request;
    }
}

您可以像这样使用:

downlaodfile = new WebClientEx(0, 600000);
downlaodfile.DownloadFileAsync(new Uri(video.DownloadUrl), @"C:\Videofile.pm4");

或者只需使用HttpWebRequest类而不是WebClient

var request = (HttpWebRequest)WebRequest.Create(video.DownloadUrl);
request.AddRange(0, 600000);
using (var response = await request.GetResponseAsync())
using (var stream = response.GetResponseStream())
using (var output = File.Create(@"C:\Videofile.pm4"))
{
    await stream.CopyToAsync(output);
}

或者如果您更喜欢使用HttpClient

var client = new HttpClient();
client.DefaultRequestHeaders.Range = new RangeHeaderValue(0, 600000);
using (var stream = await client.GetStreamAsync(video.DownloadUrl))
using (var output = File.Create(@"C:\Videofile.pm4"))
{
    await stream.CopyToAsync(output);
}

谢谢您的建议。我决定放弃WebClient,改用WebRequest来进行Range Byte操作,并且已经成功实现了。 - Evgeni Tanchev

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