Fork me on GitHub

C#队列、多线程根据URL下载文件

复制代码
/// <summary>
/// 下载辅助类
/// </summary>
public class DownFileHelper
{
    /// <summary>
    /// 构造函数
    /// </summary>
    static DownFileHelper()
    {
        Start();
    }
    private static object lockObject = new object();
    /// <summary>
    /// 下载对象的队列
    /// </summary>
    private static Queue<FlieWL> ListQueue = new Queue<FlieWL>();

    private static void Start()//启动主线程
    {
        Task.Run(() =>
        {
            threadStart();
        });
    }

    /// <summary>
    /// 常驻线程主方法--死循环保证线程不退出
    /// </summary>
    private static void threadStart()
    {
        while (true)
        {
            if (ListQueue.Count > 0)
            {
                try
                {
                    //线程锁定,一次下一个
                    lock (lockObject)
                    {
                        ScanQueue();
                    }
                }
                catch (Exception ex)
                {
                   
                }
            }
            else
            {
                //没有任务,休息3秒钟再循环
                Thread.Sleep(3000);
            }
        }
    }

    /// <summary>
    /// 要执行的方法主体 
    /// </summary>
    private static void ScanQueue()
    {
        while (ListQueue.Count > 0)
        {
            //从队列中取出一个对象
            FlieWL dwfile = ListQueue.Dequeue();
            DownFile(dwfile,true);
        }
    }

    public static async void DownFile(FlieWL jo,bool isAsync = false)
    {
        using (WebClient client = new WebClient())
        {
            try
            {
                if (jo.url.StartsWith("https"))
                {
                    ServicePointManager.ServerCertificateValidationCallback =
                       delegate { return true; };

                    //.Net4.5级以下框架需要该协议
                    //ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | (SecurityProtocolType)0xC00 //Tls12
                    // | (SecurityProtocolType)0x300; //Tls11
                    //ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
                }
                //如果调用的方法需要身份验证则必须加如下请求标头
                if (!string.IsNullOrEmpty(jo.token))
                {

                    client.Headers.Add(HttpRequestHeader.Authorization, string.Format("Bearer {0}", jo.token));
                }

                if (isAsync)
                {
                    await client.DownloadFileTaskAsync(jo.url, jo.savePath);
                }
                else
                {
                    client.DownloadFile(jo.url, jo.savePath);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }

    public static void DWFile(FlieWL fileObj)
    {
        ListQueue.Enqueue(fileObj);
    }
}


//方法调用
var files = new List<FlieWL>()
{
    new FlieWL()
    {
        fileName = "test.txt",
        url = "https://img2.wallspic.com/previews/8/1/6/9/7/179618/179618-zhi_zhu_xia-chao_ji_ying_xiong-dian_shi-spider_man_no_way_home-zhi_zhu_xia_hui_jia-550x310.jpg",
        Ext = ".png",
    },
    new FlieWL()
    {
        fileName = "test.txt",
        url = "https://img2.wallspic.com/previews/8/1/6/9/7/179618/179618-zhi_zhu_xia-chao_ji_ying_xiong-dian_shi-spider_man_no_way_home-zhi_zhu_xia_hui_jia-550x310.jpg",
        Ext = ".png",
    }
};
SaveAsAttachment(files, true);
Console.ReadKey();

/// <summary>
/// 保存url文件为附件
/// </summary>
/// <param name="joL"></param>
/// <param name="isThread">采用多线程方式,将无法进行错误阻止</param>
/// <returns></returns>
static string SaveAsAttachment(List<FlieWL> joL, bool isThread = false)
{
    //存放的路径
    string savePath = @"C:\Temp\Attachments\";

    var res = "";
    var listAtt = new List<AttachmentInfo>();
    foreach (var jo in joL)
    {
        AttachmentInfo attachment = new AttachmentInfo();
        listAtt.Add(attachment);
        var fileName = jo.fileName;
        if (string.IsNullOrEmpty(jo.Ext.ToString()))
            throw new Exception("文件扩展名为空。");
        if (string.IsNullOrEmpty(jo.fileName.ToString()))
            throw new Exception("文件名为空。");
        if (string.IsNullOrEmpty(jo.url.ToString()))
            throw new Exception("下载地址为空。");
        string url = Convert.ToString(jo.url);
        string fileId = GetNewFileID();
        //保存文档至目的地
        string filepath = savePath + fileId;
        var dirPath = savePath.Substring(0, savePath.LastIndexOf(@"\"));
        if (!Directory.Exists(dirPath))
            Directory.CreateDirectory(dirPath);
        attachment.FileID = fileId;
        attachment.Ext = jo.Ext.ToString();
        attachment.Name = jo.fileName.ToString();
        res += fileId + ";";
        attachment.LastUpdate = DateTime.Now;
        attachment.OwnerAccount = "TestMember";

        jo.url = url;
        jo.savePath = filepath;
        jo.fileID = fileId;
        attachment.Size = jo.Size;

        if (isThread)
        {
            //加入队列
            DownFileHelper.DWFile(jo);
        }
        else
        {
            DownFileHelper.DownFile(jo, isThread);
        }

        //拿到attachment信息存数据库操作,k保存的文件是没有后缀的,当文件需要预览的时候就可以直接根据ID找到文件拼接上文件后缀
    }
    return res.TrimEnd(';');
}

/// <summary>
/// 获取文件ID
/// </summary>
static string GetNewFileID()
{
    Random random = new();
    return DateTime.Now.ToString("yyyyMMddHHmmss") + random.Next(1, 10000);
}
复制代码

 

posted @   WantRemake  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示