C# 使用 HttpClient 和 FileStream 下载文件

本章讲述:C# 使用 HttpClient 和 FileStream 下载文件的方法

  为了实现一个支持暂停、继续和取消功能的文件下载器,我们可以使用 HttpClient 和 FileStream 来处理文件下载。同时,我们可以通过控制台输入来管理这些操作。

  以下是一个完整的示例代码:使用 ReadAsStreamAsync,在读取内容时先将其转换为流,然后再读取流中的数据。这样可以避免直接在 await 后面使用表达式(while ((bytesRead = await response.Content.ReadAsByteArrayAsync(buffer)) > 0)),出现CS1503错误。

using System;
using System.IO;
using System.Net.Http;
using System.Threading;

namespace FileDownloaderApp
{
    class Program
    {
        static CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        static bool isDownloading = false;

        static async void DownloadFile(string url, string savePath)
        {
			isDownloading = true;
            using (HttpClient client = new HttpClient())
            {
                // 获取文件大小
                var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
                long totalBytesToWrite = response.Content.Headers.ContentLength ?? 0;

                if (totalBytesToWrite == 0)
                {
                    Console.WriteLine("无法获取文件大小。");
                    return;
                }

                // 创建保存文件的流
				using (FileStream fileStream = new FileStream(savePath, FileMode.Create))
				{
					byte[] buffer = new byte[1024 * 64]; // 缓冲区大小,可以根据需要调整

					long totalBytesWritten = 0;
					using (var stream = await response.Content.ReadAsStreamAsync())
					{
						int bytesRead;
						while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
						{
							fileStream.Write(buffer, 0, bytesRead);

							// 计算已下载的字节数
							totalBytesWritten += bytesRead;
							double progressPercentage = Math.Round((totalBytesWritten / (double)totalBytesToWrite) * 100, 2);

							Console.Clear(); // 清除控制台内容
							Console.WriteLine($"正在下载文件... {progressPercentage}% 完成");

							if (cancellationTokenSource.Token.IsCancellationRequested)
							{
								Console.WriteLine("下载已取消。");
								return;
							}

							await Task.Delay(10); // 简单的延时,避免CPU占用过高

							if (progressPercentage >= 95)
							{
								Console.ForegroundColor = ConsoleColor.Green;
								Console.WriteLine("下载完成!");
								Console.ResetColor();
								isDownloading = false;
								break;
							}
						}
					}
				}
            }
        }

        static void Main(string[] args)
        {
            string url = "https://example.com/path/to/file.zip"; // 替换为实际的URL
            string savePath = @"C:\path\to\save\file.zip"; // 替换为你希望保存的位置

            Console.WriteLine("开始下载文件...");
            DownloadFile(url, savePath);

            while (isDownloading)
            {
                Console.WriteLine("\n请输入命令:");
                Console.WriteLine("1. 暂停");
                Console.WriteLine("2. 继续");
                Console.WriteLine("3. 取消");

                string input = Console.ReadLine();
                switch (input)
                {
                    case "1":
                        if (!cancellationTokenSource.Token.IsCancellationRequested)
                        {
                            cancellationTokenSource.Cancel();
                            Console.WriteLine("下载已暂停。");
                        }
                        break;
                    case "2":
                        if (cancellationTokenSource.Token.IsCancellationRequested)
                        {
                            cancellationTokenSource = new CancellationTokenSource();
                            isDownloading = true;
                            DownloadFile(url, savePath);
                        }
                        break;
                    case "3":
                        cancellationTokenSource.Cancel();
                        Console.WriteLine("下载已取消。");
                        isDownloading = false;
                        break;
                }

                if (cancellationTokenSource.Token.IsCancellationRequested)
                {
                    Console.WriteLine("下载已取消,退出程序。");
                    break;
                }
            }
        }
    }
}

  代码说明
    获取文件大小:使用HttpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead)来获取文件的头部信息,从而确定文件总大小。

    创建保存文件的流:使用FileStream来保存下载的内容到指定路径。

    取消操作:通过CancellationTokenSource来支持暂停和继续下载。当用户请求取消时,会抛出OperationCanceledException。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值