Simple Open Source Multithread Segmented Download Classes

01/22/2013 21:24 -AmA-#1
Hier eine kleine Spielerei die ich mal gemacht habe, daher eigentlich nicht ausreichend getestet, sieht auch nicht so schön aus und mir ists egal was mit dem Code angestellt wird. Das ganze wurde in C# geschireben. Es sollte lediglich zum herumspielen oder sonst was animieren. Die zwei Klassen sollten eigentlich für sich selber sprechen. Der Code wird nicht weiter erklärt ausser folgende Punkte:

Folgende Namespaces werden gebraucht:
PHP Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Windows.Forms;
using System.Threading
Irgendwo in eurem Code sollte
PHP Code:
System.Net.ServicePointManager.DefaultConnectionLimit 1000
vorhanden sein weil sonst nur standardmässig 2 Verbindungen aufgebaut werden können.

Hier sind die zwei Klassen:
PHP Code:
    class Download
    
{
        private 
FileStream _file;
        private 
string _url;
        private 
int _countthreads;
        private 
int _timeout;
        private 
long _contentlength;
        private List<
Segment_segmentList;
        private List<
Thread_threadList;

        public 
Download(string urlint timeout 5000)
        {
            
_url url;
            
_timeout timeout;
            
_segmentList = new List<Segment>();
            
_threadList = new List<Thread>();
        }

        public 
long GetFileSize()
        {
            
long contentLength;

            try
            {
                
WebRequest req HttpWebRequest.Create(_url);
                
req.Timeout _timeout;
                
req.Method "HEAD";
                
WebResponse resp req.GetResponse();
                
contentLength Convert.ToInt64(resp.Headers.Get("Content-Length"));
                
resp.Close();

                return 
contentLength;
            }
            catch (
Exception)
            {
                try
                {
                    
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(_url);
                    
req.Timeout _timeout;
                    
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                    
contentLength resp.ContentLength;
                    
resp.Close();

                    return 
contentLength;
                }
                catch (
Exception)
                {
                    return -
1;
                }
            }
        }

        public 
void createDownload(FileStream filelong contentLengthint countthreads)
        {
            
_countthreads countthreads;
            
_file file;
            
_contentlength contentLength;

            for (
int i 0_countthreadsi++)
            {
                
long segmentstart;
                
long segmentstop;

                if (
!= 0)
                {
                    
segmentstart Convert.ToInt64(Math.Round(_contentlength / (double)(_countthreads) * (i), 0));
                    
segmentstop Convert.ToInt64(Math.Round(_contentlength / (double)(_countthreads) * (1), 0));
                    
segmentstart++;
                }
                else
                {
                    
segmentstart 0;
                    
segmentstop Convert.ToInt64(Math.Round(_contentlength / (double)(_countthreads) * (1), 0));
                }

                
Segment segment = new Segment(file_urlsegmentstartsegmentstop);
                
segment.finished += new EventHandler(finishedSegment);
                
_threadList.Add(segment.prepare());
                
_segmentList.Add(segment);
            }

            for (
int i 0_threadList.Counti++)
            {
                
_threadList[i].Start();
            }
        }

        public 
FileStream createFile()
        {
            
SaveFileDialog dialog = new SaveFileDialog();
            
dialog.ShowDialog();
            if (
dialog.FileName != "")
            {
                return (
FileStream)dialog.OpenFile();
            }
            else
            {
                throw new 
Exception("Fail!");
            }
        }

        public 
void finishedSegment(object segEventArgs args)
        {
            if (
_segmentList.Count 1)
            {
                
_segmentList.Remove((Segment)seg);
            }
            else
            {
                
_segmentList.Remove((Segment)seg);
                
_file.Close();
            }
        }

        public List<
long[]> getStats()
        {
            List<
long[]> stats = new List<long[]>();

            foreach (
Segment seg in _segmentList)
            {
                
long[] stat seg.getStats();
                
stats.Add(stat);
            }

            return 
stats;
        }
    } 
PHP Code:
    class Segment
    
{
        public 
event EventHandler finished;
        private 
FileStream _fs;
        private 
Stream _downstream;
        private 
long _start;
        private 
long _end;
        private 
long _downloaded;
        private 
int _bufferlength;
        private 
string _url;
        private 
Thread _loaderThread;
        private 
HttpWebResponse _resp;

        public 
Segment(FileStream fsstring urllong startlong endint bufferlength 256)
        {
            
_fs fs;
            
_start start;
            
_end end;
            
_downloaded 0;
            
_bufferlength bufferlength;
            
_url url;
        }

        public 
Thread prepare()
        {
            try
            {
                
HttpWebRequest part = (HttpWebRequest)WebRequest.Create(_url);
                
part.AddRange(_start);
                
_resp = (HttpWebResponse)part.GetResponse();
                
_downstream _resp.GetResponseStream();
                
_loaderThread = new Thread(delegate() { doLoad(); });
                return 
_loaderThread;
            }
            catch (
Exception)
            {
                throw new 
Exception("Segmentierter Download konnte nicht erstellt werden!");
            }
        }

        private 
void doLoad()
        {
            
bool nextbytes true;
            
byte[] buffer = new byte[_bufferlength];
            
int howmuchread 0;
            
long pos 0;

            while ((
howmuchread _downstream.Read(buffer0_bufferlength)) != && nextbytes)
            {
                if (
_end != -1)
                {
                    if (
_start pos howmuchread _end)
                    {
                        
howmuchread -= (int)((pos + (long)howmuchread) - (_end _start));
                        
nextbytes false;
                    }
                }

                
writeFile(_fsbuffer, (int)(_start pos), howmuchread);
                
pos += howmuchread;
                
_downloaded += howmuchread;
            }

            
_downstream.Close();
            
_resp.Close();

            if (
finished != null)
            {
                
finished(this, new EventArgs());
            }
        }

        public 
void writeFile(FileStream fsbyte[] bufferint startint size)
        {
            if (!
Monitor.TryEnter(fs2000))
            {

            }
            else
            {
                try
                {
                    
fs.Seek(startSeekOrigin.Begin);
                    
fs.Write(buffer0size);
                }
                
finally
                
{
                    
Monitor.Exit(fs);
                }
            }
        }

        
internal long[] getStats()
        {
            
long[] stat = new long[3];
            
stat[0] = _start;
            
stat[1] = _downloaded;
            
stat[2] = _end;

            return 
stat;
        }
    } 
Viel Spass