多线程分段下载DownLoader代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Threading;


namespace MyDownLoader
{
  //界面控件不能由非此创建的线程操作,所以用了一个Deletgate
    //启多个线程下载,全部完成后再整合
    public class Context
    {
        public int fileIndex;//每个线程接收文件的序号

        public int fileStart;//每个线程接收文件的起始位置

        public int fileSize;//每个线程接收文件的大小


    }
    public partial class Form1 : Form
    {
        delegate void ShowProgressDelegate(object newPos);
        AutoResetEvent[] resets = null;
        public string strurl;//接受文件的URL

        public bool hb;//文件合并标志

        public int tCount;//进程数

        HttpWebRequest request = null;
        public Form1()
        {

            InitializeComponent();
           // System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Intil();
        }

        private void Intil()
        {
           // string strUrl = "http://www.jingmaizi.com.img.800cdn.com/pic/1-1-%E5%85%A8%E6%99%AFB.jpg";
            string strUrl = textBox1.Text;//"http://tyst.migu.cn/public/ringmaker01/2009%E5%B9%B43%E6%9C%88/%E8%BF%87%E6%9C%9F%E6%8C%AF%E9%93%83%E8%A1%A5%E4%BA%A7%E5%93%81/%E5%85%A8%E6%9B%B2%E8%AF%95%E5%90%AC/Mp3_128_44_16/Extreme%20Ways-Moby%20(%E9%AD%94%E6%AF%94).mp3?msisdn\u003d8ff1025a9cdf";
            tCount = Convert.ToInt32(textBox2.Text.Trim().ToString());
            object Extension = System.IO.Path.GetExtension(strUrl) as object;

            int size = 0;
            try
            {
                request = (HttpWebRequest)HttpWebRequest.Create(strUrl);
                size = (int)request.GetResponse().ContentLength;
                request.Abort();
            }
            catch
            {
                throw;
            }

            int fileTreadSize = size / tCount;//每个线程需要处理的文件大小,均分
            int fileRemains = fileTreadSize + (int)fileTreadSize % tCount;//剩下的交由一个线程处理
            resets = new AutoResetEvent[tCount];
            for (int i = 0; i < tCount; i++)
            {
                Context content = new Context();
                resets[i] = new AutoResetEvent(false);

                content.fileIndex = i;
                if (i < tCount - 1)
                {
                    content.fileStart = fileTreadSize * i;
                    content.fileSize = fileTreadSize - 1;
                }
                else
                {
                    content.fileStart = fileTreadSize * i;
                    content.fileSize = fileRemains - 1;
                }

                Thread t = new Thread(Receive);
                t.Start(content);

            }
            WaitHandle.WaitAll(resets);
            Thread hbth = new Thread(new ParameterizedThreadStart(CombineFiles));

            hbth.Start(Extension);
            MessageBox.Show("下载完毕");
        }

        /// <summary>
        /// 开始下载文件
        /// </summary>
        /// <param name="content"></param>
        private void Receive(object content)
        {
            Context Context = (Context)content;
            byte[] nbytes = new byte[512];

            string DownLoadPath = @"D:\我的文档\Downloads\";
            
            //string strUrl = "http://www.jingmaizi.com.img.800cdn.com/pic/1-1-%E5%85%A8%E6%99%AFB.jpg";
            string strUrl = "http://tyst.migu.cn/public/ringmaker01/2009%E5%B9%B43%E6%9C%88/%E8%BF%87%E6%9C%9F%E6%8C%AF%E9%93%83%E8%A1%A5%E4%BA%A7%E5%93%81/%E5%85%A8%E6%9B%B2%E8%AF%95%E5%90%AC/Mp3_128_44_16/Extreme%20Ways-Moby%20(%E9%AD%94%E6%AF%94).mp3?msisdn\u003d8ff1025a9cdf";
            try
            {
               
                FileStream fs = new FileStream(DownLoadPath + Context.fileIndex + ".dat", System.IO.FileMode.Create);

                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(strUrl);

                request.AddRange(Context.fileStart, Context.fileStart + Context.fileSize);
                System.IO.Stream ns = request.GetResponse().GetResponseStream();

                int nreadsize = ns.Read(nbytes, 0, 512);

                Thread _progressThread;
                _progressThread = new Thread(new ParameterizedThreadStart(ProgressStart));
                _progressThread.Start(Context.fileIndex);
                
                while (nreadsize > 0)
                {
                    fs.Write(nbytes, 0, nreadsize);
                    nreadsize = ns.Read(nbytes, 0, 512);

                }
                fs.Close();

                ns.Close();
                resets[Context.fileIndex].Set();
            }
            catch (Exception ex)
            { MessageBox.Show(ex.ToString()); }
            finally
            {

            }


        }
        private void ProgressStart(object index)
        {
            ShowProgress(index);
        }
        public void ShowProgress(object Index)
        {// 判断是否在线程中访问
            if (!listView1.InvokeRequired)
            {
                
                listView1.Items.Add(new ListViewItem(new string[] { "线程" + ((int)Index).ToString() + "正在下载..." }));
            }
            else
            {
                ShowProgressDelegate showProgress = new ShowProgressDelegate(ShowProgress);
                // 如使用Invoke会等到函数调用结束,而BeginInvoke不会等待直接往后走
                this.BeginInvoke(showProgress, new object[] { Index });

                
            }
        }

        /// <summary>
        /// 整合下载的文件
        /// </summary>
        private void CombineFiles(object extension)
        {
          
          //  fs = new FileStream(textBox2.Text.Trim().ToString(), System.IO.FileMode.Create);
            string DownLoadPath = @"D:\我的文档\Downloads\";

            string p = @"D:\我的文档\Downloads\";
            string pp = p + DateTime.Now.ToString("yyyyMMddHHmss") + ".mp3" ;
            string[] files = System.IO.Directory.GetFiles(p, "*.dat");
            Array.Sort(files);

            System.IO.FileStream fileStreamReader;
            //追加流
            System.IO.FileStream fileStreamWriter = new System.IO.FileStream(pp, System.IO.FileMode.Create, System.IO.FileAccess.Write);
            foreach (string s in files)
            {
                fileStreamReader = new System.IO.FileStream(s, System.IO.FileMode.Open, System.IO.FileAccess.Read);
                byte[] bytes = new byte[fileStreamReader.Length];
                fileStreamReader.Read(bytes, 0, bytes.Length);
                fileStreamReader.Close();

                //byte数组追加
                fileStreamWriter.Write(bytes, 0, bytes.Length);

            }
            fileStreamWriter.Flush();
            fileStreamWriter.Close();


        }



    }
}


1.得到服务器下载文件的大小,然后在本地设置一个临时文件和服务器端文件大小一致 a)获得访问网络地址 b)通过URL对象的openConnection()方法打开连接,返回一个连接对象 c)设置请求头 i.setRequestMethod ii.setConnectTimeout iii.setReadTimeout d)判断是否响应成功 e)获取文件长度(getContentLength()) f)随机访问文件的读取与写入RandomAccessFile(file, mode) g)设置临时文件与服务器文件大小一致(setLength()) h)关闭临时文件 2.计算出每个线程下载的大小(开始位置,结束位置) a)计算出每个线程下载的大小 b)for循环,计算出每个线程的开始、结束位置 c)最后一个线程处理 3.每创建好一次就要开启线程下载 a)构造方法 b)通过URL对象的openConnection()方法打开连接,返回一个连接对象 c)设置请求头 i.setRequestMethod ii.setConnectTimeout d)判断是否响应成功(206) e)获取每个线程返回的流对象 f)随机访问文件的读取与写入RandomAccessFile(file, mode) g)指定开始位置 h)循环读取 i.保存每个线程下载位置 ii.记录每次下载位置 iii.关闭临时记录位置文件 iv.随机本地文件写入 v.记录已下载大小 i)关闭临时文件 j)关闭输入流 4.为了杀死线程还能继续下载的情况下,从本地文件上读取已经下载文件的开始位置 a)创建保存记录结束位置的文件 b)读取文件 c)将流转换为字符 d)获取记录位置 e)把记录位置赋给开始位置 5.当你的n个线程都下载完毕的时候我进行删除记录下载位置的缓存文件 a)线程下载完就减去 b)当没有正在运行的线程时切文件存在时删除文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值