当前位置: 代码网 > it编程>编程语言>C# > C#使用HttpClient对大文件进行断点上传和下载

C#使用HttpClient对大文件进行断点上传和下载

2024年07月03日 C# 我要评论
什么是http的断点上传和下载断点上传:在向服务商上传大文件的时候,将一个大的文件拆分成多个小的文件,每个文件通过单独的http请求上传给服务器。断点下载:在向服务器请求下载一个大的资源文件的时候,不

什么是http的断点上传和下载

断点上传:在向服务商上传大文件的时候,将一个大的文件拆分成多个小的文件,每个文件通过单独的http请求上传给服务器。

断点下载:在向服务器请求下载一个大的资源文件的时候,不是一次http请求返回所有的资源文件内容。而是先通过head请求,拿到资源文件的大小(单位:字节)。然后每次请求只请求一部分字节的数据,将请求到的数据在本地进行拼接。

断点上传和下载的优点

1、避免网络中断时,重传所有资源文件内容。

2、提高服务器并发,防止单个客户端长时间和服务器保持连接。

3、可以实时显示上传和下载的进度。

断点上传和下载的缺点

1、占用更多的网络带宽,因为每次http请求都会附带各种额外的信息。

2、上传和下载的时间会变得长一点,因为是通过多次请求来完成断点上传和下载。

实现基本原理

依赖http协议的几个基本的协议头来完成断点上传和下载。

1、content-range:这是一个响应头,表示请求的资源文件大小,我们可以通过head请求拿到的资源文件的字节数,就是读取的这个字段。

2、range :这是一个请求头,表示客户端要请求的数组的范围。如如:"0-1000"、"1001-2000"、"2001-3000"等,服务器接收到这个请求头之后,只给我们返回对应范围内的资源字节数组,不会把所有的字节数都返回给我们。

一般请求下,这两个请求头就可以实现简单的断点上传和下载。本篇文章我们使用一个wpf项目演示断点下载。

string url = "http://file.cshelloworld.com/images/1771477326069108736.jpg";
long totalsize = 0;//文件总大小
long downloadingsize = 0;//当前已经下载了多少

private void button_click(object sender, routedeventargs e)
{
    task.run(async () =>
    {
        //获取到文件总大小 通过head请求
        using httpclient client = new httpclient();
        httprequestmessage requestmessage = new httprequestmessage(httpmethod.head, url);
        var response = await client.sendasync(requestmessage);
        totalsize = response.content.headers.contentlength.value;
        using filestream filestream = new filestream("d:\a.jpj", filemode.create, fileaccess.write, fileshare.read);

        //开始分片下载
        while (downloadingsize < totalsize)
        {
            //组装range 0,1000 1000,2000 0,9999
            long start = downloadingsize;
            long end = start + 1000;
            if (end > (totalsize - 1))
            {
                end = totalsize - 1;
            }
            client.defaultrequestheaders.range = new system.net.http.headers.rangeheadervalue(start, end);
            var res = await client.getasync(url);
            byte[] bytes = await res.content.readasbytearrayasync();
            await filestream.writeasync(bytes, 0, bytes.length);
            //更新ui的进度
            downloadingsize += bytes.length;
            int process = (int)((downloadingsize / (decimal)totalsize) * 100);
            this.dispatcher.invoke(() =>
            {
                cont.text = process + "%";
                this.processbar.value = process;
            });
        }
        filestream.close();
    });
}

在以上代码中,首先是head请求获取资源文件大小。

我们主要通过以下代码实现,通过设置httpmethod.head构建一个httprequestmessage的请求对象

httprequestmessage requestmessage = new httprequestmessage(httpmethod.head, url);

其次是断点下载过程中,range请求头如何设置:

client.defaultrequestheaders.range = new system.net.http.headers.rangeheadervalue(start, end);

每次请求到字节数组之后,我们将字节数组写入到本地的文件流中,如果网络断开,下次请求的时候,读取本地文件大小,假设本地未见大小为1000,那么我们请求的时候range就从1001开始,这样服务器就给我们返回的是1001之后的字节数组了。

当然在这个过程中,我们还要考虑一个问题,如果服务器的资源文件发生了修改会怎么样。如果我们继续下载的话 ,就会出现问题。因为客户端下载的文件都不是同一个文件。这种情况下,我们可以使用http的请求头last-modified来判断文件是否修改,这个请求头表示文件的最近一次修改时间。当我们第一次请求数据的时候可以把这个请求头的时间记录下来,后续请求如果服务器资源文件发生变化,我们就将本地文件全部删除,然后重新发起请求。

以上就是c#使用httpclient对大文件进行断点上传和下载的详细内容,更多关于c# httpclient文件上传和下载的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com