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

C#实现多线程下载文件的方法,第1张

概述本文实例讲述了C#实现多线程下载文件方法。分享给大家供大家参考。具体实现方法如下:

本文实例讲述了C#实现多线程下载文件的方法。分享给大家供大家参考。具体实现方法如下:

using System;using System.Collections.Generic;using System.linq;using System.Text;using System.IO;using System.Threading;using System.Net;namespace WfpApp{ public class MultIDownload {  #region 变量  private int _threadNum;    //线程数量  private long _fileSize;    //文件大小  private string _fileUrl;   //文件地址  private string _filename;   //文件名  private string _savePath;   //保存路径  private short _threadCompleteNum; //线程完成数量  private bool _isComplete;   //是否完成  private volatile int _downloadSize; //当前下载大小(实时的)  private Thread[] _thread;   //线程数组  private List<string> _tempfiles = new List<string>();  private object locker = new object();  #endregion  #region 属性  /// <summary>  /// 文件名  /// </summary>  public string filename  {   get   {    return _filename;   }   set   {    _filename = value;   }  }  /// <summary>  /// 文件大小  /// </summary>  public long fileSize  {   get   {    return _fileSize;   }  }  /// <summary>  /// 当前下载大小(实时的)  /// </summary>  public int DownloadSize  {   get   {    return _downloadSize;   }  }  /// <summary>  /// 是否完成  /// </summary>  public bool IsComplete  {   get   {    return _isComplete;   }  }  /// <summary>  /// 线程数量  /// </summary>  public int ThreadNum  {   get   {    return _threadNum;   }  }  /// <summary>  /// 保存路径  /// </summary>  public string SavePath  {   get   {    return _savePath;   }   set   {    _savePath = value;   }  }  #endregion  /// <summary>  /// 构造函数  /// </summary>  /// <param name="threahNum">线程数量</param>  /// <param name="fileUrl">文件Url路径</param>  /// <param name="savePath">本地保存路径</param>  public MultIDownload(int threahNum,string fileUrl,string savePath)  {   this._threadNum = threahNum;   this._thread = new Thread[threahNum];   this._fileUrl = fileUrl;   this._savePath = savePath;  }  public voID Start()  {   @R_502_6822@WebRequest request = (@R_502_6822@WebRequest)WebRequest.Create(_fileUrl);   @R_502_6822@WebResponse response = (@R_502_6822@WebResponse)request.GetResponse();   _fileSize = response.ContentLength;   int singelNum = (int)(_fileSize / _threadNum);  //平均分配   int remainder = (int)(_fileSize % _threadNum);  //获取剩余的   request.Abort();   response.Close();   for (int i = 0; i < _threadNum; i++)   {    List<int> range = new List<int>();    range.Add(i * singelNum);    if (remainder != 0 && (_threadNum - 1) == i) //剩余的交给最后一个线程     range.Add(i * singelNum + singelNum + remainder - 1);    else     range.Add(i * singelNum + singelNum - 1);    //下载指定位置的数据    int[] ran = new int[] { range[0],range[1] };    _thread[i] = new Thread(new ParameterizedThreadStart(Download));    _thread[i].name = System.IO.Path.GetfilenameWithoutExtension(_fileUrl) + "_{0}".Replace("{0}",Convert.ToString(i + 1));    _thread[i].Start(ran);   }  }  private voID Download(object obj)  {   Stream @R_502_6822@fileStream = null,localfileStram = null;   try   {    int[] ran = obj as int[];    string tmpfileBlock = System.IO.Path.GetTempPath() + Thread.CurrentThread.name + ".tmp";    _tempfiles.Add(tmpfileBlock);    @R_502_6822@WebRequest @R_502_6822@request = (@R_502_6822@WebRequest)WebRequest.Create(_fileUrl);    @R_502_6822@request.AddRange(ran[0],ran[1]);    @R_502_6822@WebResponse @R_502_6822@response = (@R_502_6822@WebResponse)@R_502_6822@request.GetResponse();    @R_502_6822@fileStream = @R_502_6822@response.GetResponseStream();    localfileStram = new fileStream(tmpfileBlock,fileMode.Create);    byte[] by = new byte[5000];    int getByteSize = @R_502_6822@fileStream.Read(by,(int)by.Length); //Read方法将返回读入by变量中的总字节数    while (getByteSize > 0)    {     Thread.Sleep(20);     lock (locker) _downloadSize += getByteSize;     localfileStram.Write(by,getByteSize);     getByteSize = @R_502_6822@fileStream.Read(by,(int)by.Length);    }    lock (locker) _threadCompleteNum++;   }   catch (Exception ex)   {    throw new Exception(ex.Message.ToString());   }   finally   {    if (@R_502_6822@fileStream != null) @R_502_6822@fileStream.dispose();    if (localfileStram != null) localfileStram.dispose();   }   if (_threadCompleteNum == _threadNum)   {    Complete();    _isComplete = true;   }  }  /// <summary>  /// 下载完成后合并文件块  /// </summary>  private voID Complete()  {   Stream mergefile = new fileStream(@_savePath,fileMode.Create);   BinaryWriter AdDWriter = new BinaryWriter(mergefile);   foreach (string file in _tempfiles)   {    using (fileStream fs = new fileStream(file,fileMode.Open))    {     BinaryReader TempReader = new BinaryReader(fs);     AdDWriter.Write(TempReader.ReadBytes((int)fs.Length));     TempReader.Close();    }    file.Delete(file);   }   AdDWriter.Close();  } }}

调用:

string @R_502_6822@Url = @"@R_502_6822@://172.28.98.96/fdimsservice/2.rar";string saveUrl = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "//" + System.IO.Path.Getfilename(@R_502_6822@Url);int threadNumber = 5;MultIDownload md = new MultIDownload(threadNumber,@R_502_6822@Url,saveUrl);md.Start();

希望本文所述对大家的C#程序设计有所帮助。

总结

以上是内存溢出为你收集整理的C#实现多线程下载文件的方法全部内容,希望文章能够帮你解决C#实现多线程下载文件的方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1255385.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存