增强WebClient的同步下载功能

WebClient是一个功能强大的类,通过直接使用或继承它可以很容易的下载各种Http和Ftp资源。在客户端程序中,我一般使用的是同步下载的方式来下载文件,然而WebClient的同步下载方法稍微薄弱了些,使得其在下载大文件方面存在很大的不足,主要体现在如下方面:

  1. 下载的时候无法取消
  2. 无法获取到下载速度

其实要实现这两方面的控制主要是要实现对ResponseStream的控制即可,然而,WebClient没有从一个统一的入口来获取ResponseStream,并不能通过简单的继承WebClient来实现该功能,因此,还需要对WebRequest进行封装,在WebRequest中返回封装的Stream,通过新的Stream实现对下载的控制(稍微修改一下也可以支持异步的)。基本形式如下:

class WebClientPlus:WebClient
{
    protected override WebResponse GetWebResponse(WebRequest request)
    {
        return base.GetWebResponse(request);
    }
}

class WebRepuestPlus:WebRequest
{
    WebRequest request;
    public WebRepuestPlus(WebRequest request)
    {
        this.request = request;
    }

    public override System.IO.Stream GetRequestStream()
    {
        return base.GetRequestStream();
    }
}

class WebStreamPlus:System.IO.Stream
{
    System.IO.Stream stream;

    public WebStreamPlus(System.IO.Stream stream)
    {
        this.stream = stream;
    }

    public override int Read(byte[] buffer, int offset, int count)
    {

        //这里可以实现速度的计算
        return stream.Read(buffer, offset, count);
    }
}

这样做后,可以通过修改代码,在WebClientPlus中保留对的WebStreamPlus引用,同时增强WebStreamPlus的功能,实现下载速度的计算(关闭直接调用其Close方法即可)。这样,就可以很容易实现我们所需要的功能了。

这种思路其实还是比较简单,就是要实现两个代理类:WebStreamPlusWebRepuestPlus。这种代理类实现简单,写起来却较麻烦,如果用代码生成器来生成比较合适(目前还没有这种代码生成器,其实用反射写这种代码生成器应该不难)。(上面的代码只是一个示意,并没有写完

按照这种思路,实现上传时候的控制也是很简单的。同样,也可以很容易扩展Webclient的功能,如对下载文件在内存中进行缓存、自动多次重连、断点续传等常用的下载功能。

原文地址:https://www.cnblogs.com/TianFang/p/1381698.html