代码拉取完成,页面将自动刷新
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Runtime.InteropServices;
namespace Span_Down_Sharp
{
class Program
{
static Program()
{
_foreColor = Console.ForegroundColor;
_backColor = Console.BackgroundColor;
Console.Title = "批量文件下载器";
}
private static ConsoleColor _foreColor;
private static ConsoleColor _backColor;
static void Main(string[] args)
{
Console.Clear();
Console.WriteLine("---------------------------------------");
Console.WriteLine("批量文件下载器 C#/.NET Core 版");
Console.WriteLine("@author spany-down-sharp");
Console.WriteLine("@author felix");
Console.WriteLine("@date 2019-04-19");
Console.WriteLine("---------------------------------------");
Console.WriteLine();
var urlFormat = Input.Read_Url("输入URL(含通配符,例如 http://www.spany.com/2019/(*).jpg): ");
var start = Input.Read_Integer("通配符数字开始(0~200): ", minValue: 0, maxValue: 200);
var end = Input.Read_Integer($"通配符数字结束({start}~{start + 200}): ", minValue: start, maxValue: start + 200);
var len = Input.Read_Integer("通配符数字长度(1~5): ", minValue: 1, maxValue: 5);
var referer = Input.Read_Url("输入Referer为破解防盗链(如果Referer中含有通配符(*),则将被当前URL替换,如无须Referer则直接回车): ", defaultValue: "https://www.baidu.com/visit");
Console.WriteLine();
var urlList = BuildUrlList(urlFormat, start, end, len);
if (urlList.Count > 0)
{
Console.WriteLine("URL列表如下: ");
foreach (var url in urlList)
{
Console.WriteLine("\t{0}", url);
}
Console.WriteLine();
var yes = Input.Read_YesOrNo($"是否开始下载?(y/n): ");
if (yes)
{
var path = Input.Read_Path(@"输入文件存储路径(例如 E:\album\travel): ");
Console.WriteLine();
StartDownload(urlList, path, referer);
}
}
else
{
Console.WriteLine("不能创建URL列表,请核对参数!");
}
Console.WriteLine();
Console.Write("按任意键退出……");
Console.ReadKey(true);
}
/// <summary>
/// 构建URL列表
/// </summary>
static IList<string> BuildUrlList(string urlFormat, int start, int end, int len)
{
if (!urlFormat.Contains("(*)"))
{
return new List<string> { urlFormat };
}
IList<string> list = new List<string>();
for (var i = start; i < end + 1; i++)
{
var tmp_url = urlFormat.Replace("(*)", i.ToString("D" + len));
list.Add(tmp_url);
}
return list;
}
/// <summary>
/// 开始下载
/// </summary>
static void StartDownload(IList<string> urlList, string path, string referer)
{
var lstUserState = new List<DownloadUserState>();
var watch = Stopwatch.StartNew();
var cursorTop = Console.CursorTop;
for (var i = 0; i < urlList.Count; i++)
{
referer = referer.Replace("(*)", urlList[i]);
var localFileName = Path.Combine(path, Path.GetFileName(urlList[i]));
var userState = new DownloadUserState(urlList[i], localFileName, referer, 30, cursorTop++);
lstUserState.Add(userState);
DownloadItem(userState);
}
Console.CursorVisible = false;
while (true)
{
if (lstUserState.All(item => item.IsCompleted))
{
watch.Stop();
Console.SetCursorPosition(0, cursorTop + 1);
var succeed = lstUserState.Count(i => i.IsSuccess);
var failed = lstUserState.Count - succeed;
var elapsed = Math.Round(watch.ElapsedMilliseconds / 1000.0, 1);
Console.WriteLine("总共下载 {0},成功 {1}, 失败 {2},耗时 {3}s", lstUserState.Count, succeed, failed, elapsed);
break;
}
Thread.Sleep(1);
}
Console.CursorVisible = true;
}
/// <summary>
/// 下载单个文件
/// </summary>
static void DownloadItem(DownloadUserState userState)
{
var fileName = Path.GetFileName(userState.LocalFileName);
Console.Write("文件 {0}", fileName);
Console.CursorLeft = userState.CursorLeft;
Console.Write("等待{0}", Environment.NewLine);
try
{
WebClient client = new WebClient();
client.Headers.Add("User_Agent", "Mozilla/5.0");
client.Headers.Add("Referer", userState.Referer);
client.DownloadFileCompleted += client_DownloadFileCompleted;
client.DownloadProgressChanged += client_DownloadProgressChanged;
client.DownloadFileAsync(new Uri(userState.UrlAddress), userState.LocalFileName, userState);
}
catch (Exception ex)
{
userState.Error = ex;
DisplayFailedDownloadState(userState);
}
}
/// <summary>
/// 下载进度改变事件
/// </summary>
static void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
var userState = e.UserState as DownloadUserState;
userState.SetProgressValue(e);
DisplayProgressDownloadState(userState);
}
/// <summary>
/// 下载完成事件
/// </summary>
static void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
var userState = e.UserState as DownloadUserState;
if (e.Error != null)
{
userState.Error = e.Error;
DisplayFailedDownloadState(userState);
}
else
{
userState.IsSuccess = true;
if (userState.Percentage != 100)
{
userState.Percentage = 100;
DisplayProgressDownloadState(userState);
}
}
userState.IsCompleted = true;
}
static readonly object _sync = new object();
/// <summary>
/// 显示下载状态(失败时)
/// </summary>
static void DisplayFailedDownloadState(DownloadUserState userState)
{
lock (_sync)
{
Console.SetCursorPosition(userState.CursorLeft, userState.CursorTop);
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("下载失败!{0}", userState.Error.Message);
Console.ForegroundColor = _foreColor;
}
if (File.Exists(userState.LocalFileName))
{
File.Delete(userState.LocalFileName);
}
}
/// <summary>
/// 显示下载状态(进度)
/// </summary>
static void DisplayProgressDownloadState(DownloadUserState userState)
{
lock (_sync)
{
Console.SetCursorPosition(userState.CursorLeft, userState.CursorTop);
Console.Write("{0}KB", Math.Round(userState.TotalBytes / 1024.0)); //258KB
Console.CursorLeft = userState.CursorLeft + 12;
if (userState.Percentage == 100)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("完成".PadRight(20, ' '));
Console.ForegroundColor = _foreColor;
}
else
{
var receivedBytesDisplay = $"{Math.Round(userState.ReceivedBytes / 1024.0)}KB".PadRight(8, ' ');
Console.Write("已下载 {0} {1}%", receivedBytesDisplay, userState.Percentage); //已下载 220KB 65%
}
}
}
}
/// <summary>
/// 下载状态
/// </summary>
public class DownloadUserState
{
public string UrlAddress { get; set; }
public string LocalFileName { get; set; }
public string Referer { get; set; }
public int CursorLeft { get; set; }
public int CursorTop { get; set; }
public int Percentage { get; set; }
public long TotalBytes { get; set; }
public long ReceivedBytes { get; set; }
public bool IsSuccess { get; set; }
public bool IsCompleted { get; set; }
public Exception Error { get; set; }
public DownloadUserState() { }
public DownloadUserState(string urlAddress, string localFileName, string referer, int cursorLeft, int cursorTop)
{
this.UrlAddress = urlAddress;
this.LocalFileName = localFileName;
this.Referer = referer;
this.CursorLeft = cursorLeft;
this.CursorTop = cursorTop;
}
public void SetProgressValue(DownloadProgressChangedEventArgs e)
{
this.Percentage = e.ProgressPercentage;
this.TotalBytes = e.TotalBytesToReceive;
this.ReceivedBytes = e.BytesReceived;
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。