C# 基于HttpClient支持续传的网络下载

现在网上很多的网络下载使用的都是WebResponse,使用的时候微软也会告诉我们这玩意已经过时了,推荐我们使用HttpClient,但是网上少有这个库的轮子,所以现在我们来造一个:

本文仅仅介绍核心用法,以及部分业务,具体业务可以自行添加

var httpClient= new HttpClient();

// 如果是续传,获取已经下载了多少
var downloadProgress= new FileInfo(文件存放地址).Length;

 tips:这里获得已经下载文件的大小,为后面的续传做准备

var request = new HttpRequestMessage(HttpMethod.Get, 下载的URL链接);

//从指定位置开始下载文件,这样子可以实现断点续传
request.Headers.Range = new RangeHeaderValue(downloadProgress, null);

这样子就可以实现从指定大小位置去下载,完成断点续传。

using (var response = await client.SendAsync(request))
{
    //检查请求是否成功,官方语法糖封装
    response.EnsureSuccessStatusCode();

    //这个是总下载量,也就是URL的东西一共有多大
    var totalLength = response.Content.Headers.ContentRange.Length;

    using var stream = await response.Content.ReadAsStreamAsync();

    //启用文件追加模式,确保之前下载一半的文件还能被续上
    using var fileStream = new FileStream(文件存放地址, FileMode.Append,FileAccess.Write);

    //传输层的优化buffer大小一般在4KB左右,选择4KB可以与传输层匹配,减少copying数据的次数,提高效率
     var buffer = new byte[4096];
     int read;

     //缓存已下载的字节数量,到达一个阈值再通知界面变更,根据业务随便变更
     var temp = 0;

     //每次读取一个buffer的量,处理逻辑,写入文件
     while ((read = await stream.ReadAsync(buffer)) > 0)
     {
        //外部传入的CancellationToken,用于随时取消下载任务
        XXX.CancellationToken.ThrowIfCancellationRequested();

        //将字节数追加写入文件
        await fileStream.WriteAsync(buffer.AsMemory(0, read));
        downloaded += read;
        temp += read;

        //这里以例子以百分之一进度为阈值更新界面,也可以全部通知出去,不沾染业务
        if (temp > totalLength / 100)
        {
            //这里触发需要触发的回调函数
            回调((double)((double)downloadProgress/ totalLength) * 100);
            temp = 0;
        }
     }
}

部分地方填入自己的代码,可以实现取消,暂停,续传等功能

由于该方法需要外界传入的参数比较多,>=5个(lindexi推荐参数(•̀ᴗ•́)و),所以建议封装成一个类,下面给出Demo仅供参考

public class DownloadModel
{
    /// <summary>
    /// 需要下载的URL路径
    /// </summary>
    public string Url { get; set; }

    /// <summary>
    /// 文件下载后保存的路径
    /// </summary>
    public string LocalSaveFullPath { get; set; }

    /// <summary>
    /// 是否是续点下载
    /// </summary>
    public bool Iscontinue { get; set; }

    /// <summary>
    /// 进度条回报方法
    /// </summary>
    public Action<double> ProgressRollBack { get; set; }

    /// <summary>
    /// 取消
    /// </summary>
    public CancellationToken CancellationToken { get; set; }
}

这样一个基于HttpClient支持续传的网络下载就OK了

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java的HttpClient库可以用于实现HTTP文件上,而断点续则是通过在请求头中添加"Range"字段来实现的。下面是一个简单的Java代码示例,演示了如何使用HttpClient库实现HTTP大文件的断点续: ```java import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.FileEntity; import org.apache.http.impl.client.DefaultHttpClient; public class HttpResumeUpload { public static void main(String[] args) throws IOException { String url = "http://example.com/upload"; String filePath = "/path/to/file"; int bufferSize = 1024 * 1024; // 每次上的字节数 RandomAccessFile file = new RandomAccessFile(filePath, "r"); long fileSize = file.length(); HttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost(url); post.setHeader("Range", String.format("bytes=%d-%d", 0, bufferSize - 1)); // 设置上起始位置 post.setHeader("Content-Length", String.valueOf(bufferSize)); // 设置上数据长度 HttpEntity entity = new FileEntity(file.getFD(), 0, bufferSize); post.setEntity(entity); HttpResponse response = client.execute(post); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == 206) { // 部分上成功 InputStream inputStream = response.getEntity().getContent(); byte[] buffer = new byte[1024]; int bytesRead = 0; while ((bytesRead = inputStream.read(buffer)) != -1) { // 处理服务器返回的响应数据 } post.setHeader("Range", String.format("bytes=%d-%d", bufferSize, fileSize - 1)); // 设置下一次上起始位置 post.setHeader("Content-Length", String.valueOf(fileSize - bufferSize)); // 设置下一次上数据长度 entity = new FileEntity(file.getFD(), bufferSize, fileSize - bufferSize); post.setEntity(entity); response = client.execute(post); statusCode = response.getStatusLine().getStatusCode(); // 处理服务器返回的响应数据 } else if (statusCode == 200) { // 全部上成功 // 处理服务器返回的响应数据 } file.close(); client.getConnectionManager().shutdown(); } } ``` 在上面的代码中,我们首先打开待上的文件,然后通过HttpClient库发送一个HTTP POST请求,请求的内容是文件的一部分数据。如果服务器返回206状态码,表示部分数据上成功,我们就从服务器返回的响应中读取剩下的数据,然后设置下一次上的起始位置和长度,再次发送HTTP POST请求。如果服务器返回200状态码,表示全部数据上成功,我们就可以关闭文件和HTTP客户端了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值