本文实例讲述了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#实现多线程下载文件的方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)