我的编程空间,编程开发者的网络收藏夹
学习永远不晚

使用 C# 下载文件的多种方法小结

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

使用 C# 下载文件的多种方法小结

文件下载是一个软件开发中的常见需求。本文从最简单的下载方式开始步步递进,讲述了文件下载过程中的常见问题并给出了解决方案。并展示了如何使用多线程提升 HTTP 的下载速度以及调用 aria2 实现非 HTTP 协议的文件下载。

简单下载

在 .NET 程序中下载文件最简单的方式就是使用 WebClient 的 DownloadFile 方法:


 var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    using (var web = new WebClient())
    {
        web.DownloadFile(url,save);
    }

异步下载

该方法也提供异步的实现:


 var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    using (var web = new WebClient())
    {
        await web.DownloadFileTaskAsync(url, save);
    }

下载文件的同时向服务器发送自定义请求头

如果需要对文件下载请求进行定制,可以使用 HttpClient :


var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    var http = new HttpClient();
    var request = new HttpRequestMessage(HttpMethod.Get,url);
    //增加 Auth 请求头
    request.Headers.Add("Auth","123456");
    var response = await http.SendAsync(request);
    response.EnsureSuccessStatusCode();
    using (var fs = File.Open(save, FileMode.Create))
    {
        using (var ms = response.Content.ReadAsStream())
        {
            await ms.CopyToAsync(fs);
        }
    }

如何解决下载文件不完整的问题

以上所有代码在应对小文件的下载时没有特别大的问题,在网络情况不佳或文件较大时容易引入错误。以下代码在开发中很常见:


  var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    if (!File.Exists(save))
    {
        Console.WriteLine("文件不存在,开始下载...");
        using (var web = new WebClient())
        {
            await web.DownloadFileTaskAsync(url, save);
        }
        Console.WriteLine("文件下载成功");
    }
    Console.WriteLine("开始处理文件");
    //TODO:对文件进行处理

如果在 DownloadFileTaskAsync 方法中发生了异常(通常是网络中断或网络超时),那么下载不完整的文件将会保留在本地系统中。在该任务重试执行时,因为文件已存在(虽然它不完整)所以会直接进入处理程序,从而引入异常。

一个简单的修复方式是引入异常处理,但这种方式对应用程序意外终止造成的文件不完整无效:


 var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    if (!File.Exists(save))
    {
        Console.WriteLine("文件不存在,开始下载...");
        using (var web = new WebClient())
        {
            try
            {
                await web.DownloadFileTaskAsync(url, save);
            }
            catch
            {
                if (File.Exists(save))
                {
                    File.Delete(save);
                }
                throw;
            }
        }
        Console.WriteLine("文件下载成功");
    }
    Console.WriteLine("开始处理文件");
    //TODO:对文件进行处理

笔者更喜欢的方式是引入一个临时文件。下载操作将数据下载到临时文件中,当确定下载操作执行完毕时将临时文件改名:


var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    if (!File.Exists(save))
    {
        Console.WriteLine("文件不存在,开始下载...");
        //先下载到临时文件
        var tmp = save + ".tmp";
        using (var web = new WebClient())
        {
            await web.DownloadFileTaskAsync(url, tmp);
        }
        File.Move(tmp, save, true);
        Console.WriteLine("文件下载成功");
    }
    Console.WriteLine("开始处理文件");
    //TODO:对文件进行处理

使用 Downloader 进行 HTTP 多线程下载

在网络带宽充足的情况下,单线程下载的效率并不理想。我们需要多线程和断点续传才可以拿到更好的下载速度。

Downloader 是一个现代化的、流畅的、异步的、可测试的和可移植的 .NET 库。这是一个包含异步进度事件的多线程下载程序。Downloader 与 .NET Standard 2.0 及以上版本兼容,可以在 Windows、Linux 和 macOS 上运行。

GitHub 开源地址: https://github.com/bezzad/Downloader

NuGet 地址:https://www.nuget.org/packages/Downloader

从 NuGet 安装 Downloader 之后,创建一个下载配置:


 var downloadOpt = new DownloadConfiguration()
    {
        BufferBlockSize = 10240, // 通常,主机最大支持8000字节,默认值为8000。
        ChunkCount = 8, // 要下载的文件分片数量,默认值为1
        MaximumBytesPerSecond = 1024 * 1024, // 下载速度限制为1MB/s,默认值为零或无限制
        MaxTryAgainOnFailover = int.MaxValue, // 失败的最大次数
        OnTheFlyDownload = false, // 是否在内存中进行缓存? 默认值是true
        ParallelDownload = true, // 下载文件是否为并行的。默认值为false
        TempDirectory = "C:\\temp", // 设置用于缓冲大块文件的临时路径,默认路径为Path.GetTempPath()。
        Timeout = 1000, // 每个 stream reader  的超时(毫秒),默认值是1000
        RequestConfiguration = // 定制请求头文件
        {
            Accept = "*/*",
            AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
            CookieContainer =  new CookieContainer(), // Add your cookies
            Headers = new WebHeaderCollection(), // Add your custom headers
            KeepAlive = false,
            ProtocolVersion = HttpVersion.Version11, // Default value is HTTP 1.1
            UseDefaultCredentials = false,
            UserAgent = $"DownloaderSample/{Assembly.GetExecutingAssembly().GetName().Version.ToString(3)}"
        }
    };

创建一个下载服务:


var downloader = new DownloadService(downloadOpt);

配置事件处理器(该步骤可以省略):


// Provide `FileName` and `TotalBytesToReceive` at the start of each downloads
    // 在每次下载开始时提供 "文件名 "和 "要接收的总字节数"。
    downloader.DownloadStarted += OnDownloadStarted;

    // Provide any information about chunker downloads, like progress percentage per chunk, speed, total received bytes and received bytes array to live streaming.
    // 提供有关分块下载的信息,如每个分块的进度百分比、速度、收到的总字节数和收到的字节数组,以实现实时流。
    downloader.ChunkDownloadProgressChanged += OnChunkDownloadProgressChanged;

    // Provide any information about download progress, like progress percentage of sum of chunks, total speed, average speed, total received bytes and received bytes array to live streaming.
    // 提供任何关于下载进度的信息,如进度百分比的块数总和、总速度、平均速度、总接收字节数和接收字节数组的实时流。
    downloader.DownloadProgressChanged += OnDownloadProgressChanged;

    // Download completed event that can include occurred errors or cancelled or download completed successfully.
    // 下载完成的事件,可以包括发生错误或被取消或下载成功。
    downloader.DownloadFileCompleted += OnDownloadFileCompleted;

接着就可以下载文件了:


string file = @"D:\1.html";
    string url = @"https://www.coderbusy.com";
    await downloader.DownloadFileTaskAsync(url, file);

下载非 HTTP 协议的文件

除了 WebClient 可以下载 FTP 协议的文件之外,上文所示的其他方法只能下载 HTTP 协议的文件。

aria2 是一个轻量级的多协议和多源命令行下载工具。它支持 HTTP/HTTPS、FTP、SFTP、BitTorrent 和 Metalink。aria2 可以通过内置的 JSON-RPC 和 XML-RPC 接口进行操作。

我们可以调用 aria2 实现文件下载功能。

GitHub 地址:https://github.com/aria2/aria2

下载地址:https://github.com/aria2/aria2/releases

将下载好的 aria2c.exe 复制到应用程序目录,如果是其他系统则可以下载对应的二进制文件。


 public static async Task Download(string url, string fn)
    {
        var exe = "aria2c";
        var dir = Path.GetDirectoryName(fn);
        var name = Path.GetFileName(fn);

        void Output(object sender, DataReceivedEventArgs args)
        {
            if (string.IsNullOrWhiteSpace(args.Data))
            {
                return;
            }
            Console.WriteLine("Aria:{0}", args.Data?.Trim());
        }

        var args = $"-x 8 -s 8 --dir={dir} --out={name} {url}";
        var info = new ProcessStartInfo(exe, args)
        {
            UseShellExecute = false,
            CreateNoWindow = true,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
        };
        if (File.Exists(fn))
        {
            File.Delete(fn);
        }

        Console.WriteLine("启动 aria2c: {0}", args);
        using (var p = new Process { StartInfo = info, EnableRaisingEvents = true })
        {
            if (!p.Start())
            {
                throw new Exception("aria 启动失败");
            }
            p.ErrorDataReceived += Output;
            p.OutputDataReceived += Output;
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();
            await p.WaitForExitAsync();
            p.OutputDataReceived -= Output;
            p.ErrorDataReceived -= Output;
        }

        var fi = new FileInfo(fn);
        if (!fi.Exists || fi.Length == 0)
        {
            throw new FileNotFoundException("文件下载失败", fn);
        }
    }

以上代码通过命令行参数启动了一个新的 aria2c 下载进程,并对下载进度信息输出在了控制台。调用方式如下:


 var url = "https://www.coderbusy.com";
    var save = @"D:\1.html";
    await Download(url, save);

到此这篇关于使用 C# 下载文件的十八般武艺的文章就介绍到这了,更多相关C# 下载文件内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

使用 C# 下载文件的多种方法小结

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

VUE+ElementUI下载文件的几种方式(小结)

本文主要介绍了VUE+ElementUI下载文件的几种方式(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-01-13

Java下载文件的4种方式总结

1. 使用URL类的openStream()方法:这是最基本的下载文件的方式。通过URL.openStream()方法,可以获取到文件的输入流,然后使用输入流的read()方法来读取文件内容,并将其写入到本地文件中。2. 使用URLConn
2023-08-09

python下载文件的三种方法

# Python 2 codeimport urllibimport urllib2import requests               url = 'http://192.168.1.100/test.zip'           
2023-01-31

python下载文件的几种常用方法

python中下载文件常用的几个模块有urllib,urllib2,requests,方法也很简单,代码如下:# Python 2 codeimport urllibimport urllib2import requests        
2023-01-31

Linux删除目录下的文件的10种方法小结

看到了一遍文章,便突发奇想的想起linux中删除目录下的所有文件的方法;整理了几个,如有不足,还望读者不吝赐教! 删除当前目录下的文件 1.rm -f * #最经典的方法,删除当前目录下的所有类型的文件 2.find . -type
2022-06-04

前端vue中实现文件下载的几种方法总结

这篇文章主要介绍了前端vue中实现文件下载的几种方法总结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-05-15

Linux下查看压缩文件内容的10种方法(小结)

通常来说,我们查看归档或压缩文件的内容,需要先进行解压缩,然后再查看,比较麻烦。今天给大家介绍 10 不同方法,能够让你轻松地在未解压缩的情况下查看归档或压缩文件的内容。从技术上讲,查看归档或压缩文件不提前进行解压是不可能的。本文介绍的方法
2022-06-04

python实现下载文件的三种方法

Python开发中时长遇到要下载文件的情况,最常用的方法就是通过Http利用urllib或者urllib2模块。当然你也可以利用ftplib从ftp站点下载文件。此外Python还提供了另外一种方法requests。下面来看看三种方法是如何
2022-06-04

MySQL导入sql文件的三种方法小结

目录一、使用工具Navicat for mysql导入1.打开localhost_3306,选中右击“新建数据库”2.指定数据库名和字符集(可根据sql文件的字符集类型自行选择)3.选中数据库下的表运行SQL文件4.
2023-02-03

C#获取XML文件内容的多种方式总结

这篇文章主要介绍了C#获取XML文件内容的多种方式总结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-01-28

Golang按行读取文件的三种方法小结

本文主要介绍了Golang按行读取文件的三种方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-05-17

C# 中SqlParameter类的使用方法小结

在C#中,SqlParameter类用于表示SQL命令中的参数。以下是SqlParameter类的使用方法的小结:1. 创建SqlParameter对象:```SqlParameter parameter = new SqlParamete
2023-09-08

ASP.Net Core读取配置文件的三种方法小结

ASP.NetCore中读取配置文件有三种方法:1.使用IConfiguration:通过依赖注入获取IConfiguration对象,然后使用GetSection和GetValue方法获取配置值。2.使用OptionsPattern:创建POCO对象表示配置,使用OptionsBuilder绑定,通过DI注入获取配置对象。3.使用IConfigurationRoot:通过DI注入获取IConfigurationRoot对象,使用GetChildSection和GetValue方法获取配置值。
ASP.Net Core读取配置文件的三种方法小结
2024-04-02

Android实现打开各种文件的intent方法小结

本文实例讲述了Android实现打开各种文件的intent方法。分享给大家供大家参考,具体如下:import android.app.Activity; import Android.content.Intent; import andro
2022-06-06

Android实现多线程下载文件的方法

本文实例讲述了Android实现多线程下载文件的方法。分享给大家供大家参考。具体如下: 多线程下载大概思路就是通过Range 属性实现文件分段,然后用RandomAccessFile 来读写文件,最终合并为一个文件 首先看下效果图:创建工程
2022-06-06

Python实现HTTP协议下的文件下载方法总结

本文介绍了几种常用的python下载文件的方法,具体使用到了htttplib2,urllib等包,希望对大家有帮忙。 1.简单文件下载 使用htttplib2,具体代码如下:h = httplib2.Http() url = '
2022-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录