using
System;
using System.IO;
using System.Net;
using System.Text;
using System.Security;
using System.Threading;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Data;
namespace HttpDownload.DownloadFile
... {
/**//// <summary>
/// Download file info
/// </summary>
[Serializable()]
public class DownloadFileInfo
...{
private string _requestURL;
private string _responseURL;
private string _fileName;
private int _totalSize;
private int _blockLeftSize;
public string RequestURL
...{
get ...{ return _requestURL; }
}
public string ResponseURL
...{
get ...{ return _responseURL; }
}
public string FileName
...{
get ...{ return _fileName; }
}
public int TotalSize
...{
get ...{ return _totalSize; }
set ...{ _totalSize = value; }
}
public int BlockLeftSize
...{
get ...{ return _blockLeftSize; }
set ...{ _blockLeftSize = value; }
}
public DownloadFileInfo(string requestURL, string responseURL, string fileName, int totalSize, int blockLeftSize)
...{
this._requestURL = requestURL;
this._responseURL = responseURL;
this._fileName = fileName;
this._totalSize = totalSize;
this._blockLeftSize = blockLeftSize;
}
public DownloadFileInfo(string requestURL, string responseURL, string fileName)
: this(requestURL, responseURL, fileName, 0, 0)
...{
}
public DownloadFileInfo(string url, string fileName)
: this(url, url, fileName, 0, 0)
...{
}
private DownloadFileInfo()
...{
}
public static DownloadFileInfo CreatFileInfo(DataRow drFileInfo)
...{
DownloadFileInfo newFileInfo = new DownloadFileInfo();
newFileInfo._requestURL = drFileInfo["RequestURL"].ToString();
newFileInfo._responseURL = drFileInfo["ResponseURL"].ToString();
newFileInfo._fileName = drFileInfo["FileName"].ToString();
newFileInfo._totalSize = Convert.ToInt32(drFileInfo["TotalSize"].ToString());
newFileInfo._blockLeftSize = Convert.ToInt32(drFileInfo["BlockLeftSize"].ToString());
return newFileInfo;
}
}
/**//// <summary>
/// Download event arguments
/// </summary>
public class DownLoadEventArgs : System.EventArgs
...{
private DownloadFileInfo _downloadFileInfo;
private int _position;
private int _readCount;
private int _threadNO;
public DownloadFileInfo DownFileInfo
...{
get ...{ return _downloadFileInfo; }
}
public int StartPosition
...{
get ...{ return _position; }
}
public int ReadCount
...{
get ...{ return _readCount; }
}
public int ThreadNO
...{
get ...{ return _threadNO; }
}
public DownLoadEventArgs(DownloadFileInfo DownFileInfo, int nStartPostion, int nReadCount, int nThreadNO)
...{
this._downloadFileInfo = DownFileInfo;
this._position = nStartPostion;
this._readCount = nReadCount;
this._threadNO = nThreadNO;
}
}
/**//// <summary>
/// class for sub-download threads
/// </summary>
public class SubDownloadThread
...{
private int _threadNO;
private int _position;
private int _blockSizeLeft;
private bool _isStopped;
private Thread thdDownload;
const int BUFFER_SIZE = 0x10000;//64k buffer size
private readonly DownloadFileInfo _fileInfo;
private EventHandler _finished;
public event EventHandler<DownLoadEventArgs> DataReceived;
public SubDownloadThread(DownloadFileInfo DownFileInfo, int ThreadNO, int Position, int BlockSizeLeft, EventHandler Finished)
...{
this._fileInfo = DownFileInfo;
this._threadNO = ThreadNO;
this._position = Position;
this._blockSizeLeft = BlockSizeLeft;
this._finished = Finished;
}
/**//// <summary>
/// Start to create thread to download file
/// </summary>
public void StartDownload()
...{
thdDownload = new Thread(new ThreadStart(this.Download));
thdDownload.Start();
}
/**//// <summary>
/// Stop current download-thread
/// </summary>
public void Stop()
...{
_isStopped = true;
if (thdDownload.ThreadState == System.Threading.ThreadState.Running)
...{
thdDownload.Join(10);
}
Debug.WriteLine(string.Format("Thread NO:{0} is stopped!", _threadNO));
}
/**//// <summary>
/// Function for sub-thread
/// </summary>
private void Download()
...{
HttpWebResponse hwrp = null;
try
...{
Debug.WriteLine(string.Format("Thread NO:{0} begins to download!", _threadNO));
// Creat request by url
HttpWebRequest hwrq = (HttpWebRequest)WebRequest.Create(new Uri(this._fileInfo.RequestURL));
// Go to download position
hwrq.AddRange(_position);
// Get response from request
hwrp = (HttpWebResponse)hwrq.GetResponse();
}
catch (Exception e)
...{
Debug.WriteLine(e.Message);
return;
}
// download and write data from
Debug.WriteLine(string.Format("Thread NO:{0} call function named DownloadData!", _threadNO));
DownloadData(hwrp);
hwrp.Close();//Close response here
}
/**//// <summary>
/// Download data through web request
/// </summary>
/// <param name="Response"></param>
private void DownloadData(WebResponse Response)
...{
byte[] bBuffer = new byte[BUFFER_SIZE];
Stream sReader = Response.GetResponseStream();
if (sReader == null) return;
int nReadCount = 0;
while (!_isStopped && this._blockSizeLeft > 0)
...{
Debug.WriteLine(string.Format("Thread NO:{0} reads data!", _threadNO));
// Set read size
nReadCount = (BUFFER_SIZE > this._blockSizeLeft) ? this._blockSizeLeft : BUFFER_SIZE;//Get current read count
// Read data
int nRealReadCount = sReader.Read(bBuffer, 0, nReadCount);
if (nRealReadCount <= 0) break;
Debug.WriteLine(string.Format("Thread NO:{0} writes data!", _threadNO));
// Write data
using (FileStream sw = new FileStream(this._fileInfo.FileName + DownloadThread.filenameExt,
System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, System.IO.FileShare.ReadWrite))
...{
sw.Position = this._position;
sw.Write(bBuffer, 0, nRealReadCount);
Debug.WriteLine(string.Format("Thread NO:{0} writes {1} data!", _threadNO, nRealReadCount));
sw.Flush();
sw.Close();
}
Debug.WriteLine(string.Format("Thread NO:{0} send callback info!", _threadNO));
// Call back
EventHandler<DownLoadEventArgs> receivedHandler = DataReceived;
if (receivedHandler != null)
...{
receivedHandler(this,new DownLoadEventArgs(
this._fileInfo, this._position, nRealReadCount, this._threadNO));
}
// Set position and block left
this._position += nRealReadCount;
this._blockSizeLeft -= nRealReadCount;
}
if (_isStopped)
...{
return;
}
Debug.WriteLine(string.Format("Thread NO:{0} sends finish-info!", _threadNO));
EventHandler finishHandle = _finished;
if (finishHandle != null)
...{
finishHandle(this,EventArgs.Empty);
}
}
}
/**//// <summary>
/// Class for download thread
/// </summary>
public class DownloadThread
...{
private DownloadFileInfo _fileInfo;
private SubDownloadThread[] subThreads;
private int nThreadFinishedCount;
private DataRow drFileInfo;
private DataTable dtThreadInfo;
public EventHandler<DownLoadEventArgs> DataReceived;
public event EventHandler Finished;
public const string filenameExt = ".bf!"; //未下载完的扩展名
public DataTable ThreadInfo
...{
get ...{ return dtThreadInfo; }
}
/**//// Class's Constructor
public DownloadThread(string requestURL, string responseURL, string fileName, DataRow newFileInfo, int subThreadNum)
...{
// Create download file info
_fileInfo = new DownloadFileInfo(requestURL, responseURL, fileName);
// Create request to get file info
bool blnMultiDownload = GetFileDownInfo();
// Create file info datarow
drFileInfo = newFileInfo;
InitDataRow();
// Create subthreads and set these info in threadinfo table
if (subThreadNum <= 0) subThreadNum = 5;//Defualt value
//Not support to be multi-thread download or less than 64k
if (!blnMultiDownload || _fileInfo.TotalSize <= 0x10000) subThreadNum = 1;
subThreads = new SubDownloadThread[subThreadNum];
nThreadFinishedCount = 0;
CreateThreadTable(subThreadNum);
}
public DownloadThread(string url, string fileName)
: this(url, url, fileName, null, 2)
...{
}
public DownloadThread(DataRow downloadFileInfo, DataTable threadInfos)
...{
// Create download file info
drFileInfo = downloadFileInfo;
_fileInfo = new DownloadFileInfo(drFileInfo["RequestURL"].ToString(),
drFileInfo["ResponseURL"].ToString(),
drFileInfo["FileName"].ToString(),
Convert.ToInt32(drFileInfo["TotalSize"].ToString()),
Convert.ToInt32(drFileInfo["BlockLeftSize"].ToString()));
// Create sub thread class objects
dtThreadInfo = threadInfos;
subThreads = new SubDownloadThread[dtThreadInfo.Rows.Count];
nThreadFinishedCount = 0;
}
/**//// {Class's Constructor}
/// <summary>
/// Start to download
/// </summary>
public void Start()
...{
StartSubThreads();
}
/**//// <summary>
/// Create table to save thread info
/// </summary>
/// <param name="SubThreadNum"></param>
private void CreateThreadTable(int SubThreadNum)
...{
int nThunkSize = _fileInfo.TotalSize / SubThreadNum;
dtThreadInfo = new DataTable("DownloadFileInfo");
dtThreadInfo.Columns.Add("ThreadNO", typeof(int));
dtThreadInfo.Columns.Add("Position", typeof(int));
dtThreadInfo.Columns.Add("BlockLeftSize", typeof(int));
DataRow drNew;
int i = 0;
for (; i < SubThreadNum - 1; i++)
...{
drNew = dtThreadInfo.NewRow();
drNew["ThreadNO"] = i;
drNew["Position"] = i * nThunkSize;
drNew["BlockLeftSize"] = nThunkSize;
dtThreadInfo.Rows.Add(drNew);
}
drNew = dtThreadInfo.NewRow();
drNew["ThreadNO"] = i;
drNew["Position"] = i * nThunkSize;
drNew["BlockLeftSize"] = _fileInfo.TotalSize - i * nThunkSize;
dtThreadInfo.Rows.Add(drNew);
dtThreadInfo.AcceptChanges();
}
/**//// <summary>
/// Start sub-threads to download file
/// </summary>
private void StartSubThreads()
...{
foreach (DataRow dr in dtThreadInfo.Rows)
...{
int ThreadNO = Convert.ToInt32(dr["ThreadNO"].ToString());
if (Convert.ToInt32(dr["BlockLeftSize"].ToString()) > 0)
...{
subThreads[ThreadNO] = new SubDownloadThread(_fileInfo, ThreadNO,
Convert.ToInt32(dr["Position"].ToString()),
Convert.ToInt32(dr["BlockLeftSize"].ToString()),
new EventHandler(this.DownloadFinished));
subThreads[ThreadNO].DataReceived += this.DataReceived;
subThreads[ThreadNO].StartDownload();
}
else
...{
DownloadFinished(this,EventArgs.Empty);
}
}
}
/**//// <summary>
/// Save download file info
/// </summary>
private void InitDataRow()
...{
if (drFileInfo != null)
...{
drFileInfo.BeginEdit();
drFileInfo["RequestURL"] = _fileInfo.RequestURL;
drFileInfo["ResponseURL"] = _fileInfo.ResponseURL;
drFileInfo["FileName"] = _fileInfo.FileName;
drFileInfo["TotalSize"] = _fileInfo.TotalSize;
drFileInfo["BlockLeftSize"] = _fileInfo.BlockLeftSize;
drFileInfo["CreatedTime"] = DateTime.Now.ToString("yyyyMMddHHmmss");
drFileInfo.EndEdit();
drFileInfo.AcceptChanges();
}
}
/**//// <summary>
/// Check url to get download file info
/// </summary>
/// <returns></returns>
private bool GetFileDownInfo()
...{
HttpWebRequest hwrq;
HttpWebResponse hwrp = null;
try
...{
//Create request
hwrq = (HttpWebRequest)WebRequest.Create(_fileInfo.RequestURL);
hwrp = (HttpWebResponse)hwrq.GetResponse();
//Get file size info
long L = hwrp.ContentLength;
L = ((L == -1) || (L > 0x7fffffff)) ? ((long)0x7fffffff) : L;
_fileInfo.TotalSize = (int)L;
_fileInfo.BlockLeftSize = _fileInfo.TotalSize;
//Check whether this url is supported to be multi-threads download
bool blnMulti = (hwrp.Headers["Accept-Ranges"] != null && hwrp.Headers["Accept-Ranges"] == "bytes");
hwrp.Close();//Close response here
return blnMulti;
}
catch (Exception e)
...{
throw e;
}
}
/**//// <summary>
/// Update download thread info
/// </summary>
/// <param name="ThreadNO"></param>
/// <param name="Position"></param>
/// <param name="DownloadSize"></param>
public void UpdateDownloadInfo(int ThreadNO, int Position, int DownloadSize)
...{
if (ThreadNO >= dtThreadInfo.Rows.Count)
...{
return;
}
DataRow drThreadNO = dtThreadInfo.Rows[ThreadNO];
drThreadNO["Position"] = Position + DownloadSize;
drThreadNO["BlockLeftSize"] = Convert.ToInt32(drThreadNO["BlockLeftSize"].ToString())
- DownloadSize;
drThreadNO.AcceptChanges();
drFileInfo["BlockLeftSize"] = Convert.ToInt32(drFileInfo["BlockLeftSize"].ToString()) - DownloadSize;
}
/**//// <summary>
/// Stop download threads
/// </summary>
public void Stop()
...{
for (int i = 0; i < subThreads.Length; i++)
...{
subThreads[i].Stop();
}
}
/**//// <summary>
/// Thread download finished
/// </summary>
private void DownloadFinished(object sender,EventArgs e)
...{
// Some download thread finished
nThreadFinishedCount++;
if (nThreadFinishedCount == subThreads.Length)
...{
// All download threads finished
if (drFileInfo != null)
...{
drFileInfo.Delete();
drFileInfo.AcceptChanges();
}
File.Move(_fileInfo.FileName + filenameExt, GetNewFilename(_fileInfo.FileName));
EventHandler handler = Finished;
if (handler != null)
...{
handler(this,EventArgs.Empty);
}
}
}
/**//// <summary>
/// 得到新名称
/// </summary>
/// <returns></returns>
public static string GetNewFilename(string filename)
...{
if (File.Exists(filename))
...{
string newname = filename;
int i = 0;
int lastPoint = filename.LastIndexOf('.');
do
...{
i++;
if (lastPoint < 1)
...{
newname = filename + "(" + i + ")";
}
else
...{
newname = filename.Substring(0, lastPoint) + "(" + i + ")" + filename.Substring(lastPoint);
}
}
while (File.Exists(newname));
return newname;
}
else
...{
return filename;
}
}
}
}
using System.IO;
using System.Net;
using System.Text;
using System.Security;
using System.Threading;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Data;
namespace HttpDownload.DownloadFile
... {
/**//// <summary>
/// Download file info
/// </summary>
[Serializable()]
public class DownloadFileInfo
...{
private string _requestURL;
private string _responseURL;
private string _fileName;
private int _totalSize;
private int _blockLeftSize;
public string RequestURL
...{
get ...{ return _requestURL; }
}
public string ResponseURL
...{
get ...{ return _responseURL; }
}
public string FileName
...{
get ...{ return _fileName; }
}
public int TotalSize
...{
get ...{ return _totalSize; }
set ...{ _totalSize = value; }
}
public int BlockLeftSize
...{
get ...{ return _blockLeftSize; }
set ...{ _blockLeftSize = value; }
}
public DownloadFileInfo(string requestURL, string responseURL, string fileName, int totalSize, int blockLeftSize)
...{
this._requestURL = requestURL;
this._responseURL = responseURL;
this._fileName = fileName;
this._totalSize = totalSize;
this._blockLeftSize = blockLeftSize;
}
public DownloadFileInfo(string requestURL, string responseURL, string fileName)
: this(requestURL, responseURL, fileName, 0, 0)
...{
}
public DownloadFileInfo(string url, string fileName)
: this(url, url, fileName, 0, 0)
...{
}
private DownloadFileInfo()
...{
}
public static DownloadFileInfo CreatFileInfo(DataRow drFileInfo)
...{
DownloadFileInfo newFileInfo = new DownloadFileInfo();
newFileInfo._requestURL = drFileInfo["RequestURL"].ToString();
newFileInfo._responseURL = drFileInfo["ResponseURL"].ToString();
newFileInfo._fileName = drFileInfo["FileName"].ToString();
newFileInfo._totalSize = Convert.ToInt32(drFileInfo["TotalSize"].ToString());
newFileInfo._blockLeftSize = Convert.ToInt32(drFileInfo["BlockLeftSize"].ToString());
return newFileInfo;
}
}
/**//// <summary>
/// Download event arguments
/// </summary>
public class DownLoadEventArgs : System.EventArgs
...{
private DownloadFileInfo _downloadFileInfo;
private int _position;
private int _readCount;
private int _threadNO;
public DownloadFileInfo DownFileInfo
...{
get ...{ return _downloadFileInfo; }
}
public int StartPosition
...{
get ...{ return _position; }
}
public int ReadCount
...{
get ...{ return _readCount; }
}
public int ThreadNO
...{
get ...{ return _threadNO; }
}
public DownLoadEventArgs(DownloadFileInfo DownFileInfo, int nStartPostion, int nReadCount, int nThreadNO)
...{
this._downloadFileInfo = DownFileInfo;
this._position = nStartPostion;
this._readCount = nReadCount;
this._threadNO = nThreadNO;
}
}
/**//// <summary>
/// class for sub-download threads
/// </summary>
public class SubDownloadThread
...{
private int _threadNO;
private int _position;
private int _blockSizeLeft;
private bool _isStopped;
private Thread thdDownload;
const int BUFFER_SIZE = 0x10000;//64k buffer size
private readonly DownloadFileInfo _fileInfo;
private EventHandler _finished;
public event EventHandler<DownLoadEventArgs> DataReceived;
public SubDownloadThread(DownloadFileInfo DownFileInfo, int ThreadNO, int Position, int BlockSizeLeft, EventHandler Finished)
...{
this._fileInfo = DownFileInfo;
this._threadNO = ThreadNO;
this._position = Position;
this._blockSizeLeft = BlockSizeLeft;
this._finished = Finished;
}
/**//// <summary>
/// Start to create thread to download file
/// </summary>
public void StartDownload()
...{
thdDownload = new Thread(new ThreadStart(this.Download));
thdDownload.Start();
}
/**//// <summary>
/// Stop current download-thread
/// </summary>
public void Stop()
...{
_isStopped = true;
if (thdDownload.ThreadState == System.Threading.ThreadState.Running)
...{
thdDownload.Join(10);
}
Debug.WriteLine(string.Format("Thread NO:{0} is stopped!", _threadNO));
}
/**//// <summary>
/// Function for sub-thread
/// </summary>
private void Download()
...{
HttpWebResponse hwrp = null;
try
...{
Debug.WriteLine(string.Format("Thread NO:{0} begins to download!", _threadNO));
// Creat request by url
HttpWebRequest hwrq = (HttpWebRequest)WebRequest.Create(new Uri(this._fileInfo.RequestURL));
// Go to download position
hwrq.AddRange(_position);
// Get response from request
hwrp = (HttpWebResponse)hwrq.GetResponse();
}
catch (Exception e)
...{
Debug.WriteLine(e.Message);
return;
}
// download and write data from
Debug.WriteLine(string.Format("Thread NO:{0} call function named DownloadData!", _threadNO));
DownloadData(hwrp);
hwrp.Close();//Close response here
}
/**//// <summary>
/// Download data through web request
/// </summary>
/// <param name="Response"></param>
private void DownloadData(WebResponse Response)
...{
byte[] bBuffer = new byte[BUFFER_SIZE];
Stream sReader = Response.GetResponseStream();
if (sReader == null) return;
int nReadCount = 0;
while (!_isStopped && this._blockSizeLeft > 0)
...{
Debug.WriteLine(string.Format("Thread NO:{0} reads data!", _threadNO));
// Set read size
nReadCount = (BUFFER_SIZE > this._blockSizeLeft) ? this._blockSizeLeft : BUFFER_SIZE;//Get current read count
// Read data
int nRealReadCount = sReader.Read(bBuffer, 0, nReadCount);
if (nRealReadCount <= 0) break;
Debug.WriteLine(string.Format("Thread NO:{0} writes data!", _threadNO));
// Write data
using (FileStream sw = new FileStream(this._fileInfo.FileName + DownloadThread.filenameExt,
System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, System.IO.FileShare.ReadWrite))
...{
sw.Position = this._position;
sw.Write(bBuffer, 0, nRealReadCount);
Debug.WriteLine(string.Format("Thread NO:{0} writes {1} data!", _threadNO, nRealReadCount));
sw.Flush();
sw.Close();
}
Debug.WriteLine(string.Format("Thread NO:{0} send callback info!", _threadNO));
// Call back
EventHandler<DownLoadEventArgs> receivedHandler = DataReceived;
if (receivedHandler != null)
...{
receivedHandler(this,new DownLoadEventArgs(
this._fileInfo, this._position, nRealReadCount, this._threadNO));
}
// Set position and block left
this._position += nRealReadCount;
this._blockSizeLeft -= nRealReadCount;
}
if (_isStopped)
...{
return;
}
Debug.WriteLine(string.Format("Thread NO:{0} sends finish-info!", _threadNO));
EventHandler finishHandle = _finished;
if (finishHandle != null)
...{
finishHandle(this,EventArgs.Empty);
}
}
}
/**//// <summary>
/// Class for download thread
/// </summary>
public class DownloadThread
...{
private DownloadFileInfo _fileInfo;
private SubDownloadThread[] subThreads;
private int nThreadFinishedCount;
private DataRow drFileInfo;
private DataTable dtThreadInfo;
public EventHandler<DownLoadEventArgs> DataReceived;
public event EventHandler Finished;
public const string filenameExt = ".bf!"; //未下载完的扩展名
public DataTable ThreadInfo
...{
get ...{ return dtThreadInfo; }
}
/**//// Class's Constructor
public DownloadThread(string requestURL, string responseURL, string fileName, DataRow newFileInfo, int subThreadNum)
...{
// Create download file info
_fileInfo = new DownloadFileInfo(requestURL, responseURL, fileName);
// Create request to get file info
bool blnMultiDownload = GetFileDownInfo();
// Create file info datarow
drFileInfo = newFileInfo;
InitDataRow();
// Create subthreads and set these info in threadinfo table
if (subThreadNum <= 0) subThreadNum = 5;//Defualt value
//Not support to be multi-thread download or less than 64k
if (!blnMultiDownload || _fileInfo.TotalSize <= 0x10000) subThreadNum = 1;
subThreads = new SubDownloadThread[subThreadNum];
nThreadFinishedCount = 0;
CreateThreadTable(subThreadNum);
}
public DownloadThread(string url, string fileName)
: this(url, url, fileName, null, 2)
...{
}
public DownloadThread(DataRow downloadFileInfo, DataTable threadInfos)
...{
// Create download file info
drFileInfo = downloadFileInfo;
_fileInfo = new DownloadFileInfo(drFileInfo["RequestURL"].ToString(),
drFileInfo["ResponseURL"].ToString(),
drFileInfo["FileName"].ToString(),
Convert.ToInt32(drFileInfo["TotalSize"].ToString()),
Convert.ToInt32(drFileInfo["BlockLeftSize"].ToString()));
// Create sub thread class objects
dtThreadInfo = threadInfos;
subThreads = new SubDownloadThread[dtThreadInfo.Rows.Count];
nThreadFinishedCount = 0;
}
/**//// {Class's Constructor}
/// <summary>
/// Start to download
/// </summary>
public void Start()
...{
StartSubThreads();
}
/**//// <summary>
/// Create table to save thread info
/// </summary>
/// <param name="SubThreadNum"></param>
private void CreateThreadTable(int SubThreadNum)
...{
int nThunkSize = _fileInfo.TotalSize / SubThreadNum;
dtThreadInfo = new DataTable("DownloadFileInfo");
dtThreadInfo.Columns.Add("ThreadNO", typeof(int));
dtThreadInfo.Columns.Add("Position", typeof(int));
dtThreadInfo.Columns.Add("BlockLeftSize", typeof(int));
DataRow drNew;
int i = 0;
for (; i < SubThreadNum - 1; i++)
...{
drNew = dtThreadInfo.NewRow();
drNew["ThreadNO"] = i;
drNew["Position"] = i * nThunkSize;
drNew["BlockLeftSize"] = nThunkSize;
dtThreadInfo.Rows.Add(drNew);
}
drNew = dtThreadInfo.NewRow();
drNew["ThreadNO"] = i;
drNew["Position"] = i * nThunkSize;
drNew["BlockLeftSize"] = _fileInfo.TotalSize - i * nThunkSize;
dtThreadInfo.Rows.Add(drNew);
dtThreadInfo.AcceptChanges();
}
/**//// <summary>
/// Start sub-threads to download file
/// </summary>
private void StartSubThreads()
...{
foreach (DataRow dr in dtThreadInfo.Rows)
...{
int ThreadNO = Convert.ToInt32(dr["ThreadNO"].ToString());
if (Convert.ToInt32(dr["BlockLeftSize"].ToString()) > 0)
...{
subThreads[ThreadNO] = new SubDownloadThread(_fileInfo, ThreadNO,
Convert.ToInt32(dr["Position"].ToString()),
Convert.ToInt32(dr["BlockLeftSize"].ToString()),
new EventHandler(this.DownloadFinished));
subThreads[ThreadNO].DataReceived += this.DataReceived;
subThreads[ThreadNO].StartDownload();
}
else
...{
DownloadFinished(this,EventArgs.Empty);
}
}
}
/**//// <summary>
/// Save download file info
/// </summary>
private void InitDataRow()
...{
if (drFileInfo != null)
...{
drFileInfo.BeginEdit();
drFileInfo["RequestURL"] = _fileInfo.RequestURL;
drFileInfo["ResponseURL"] = _fileInfo.ResponseURL;
drFileInfo["FileName"] = _fileInfo.FileName;
drFileInfo["TotalSize"] = _fileInfo.TotalSize;
drFileInfo["BlockLeftSize"] = _fileInfo.BlockLeftSize;
drFileInfo["CreatedTime"] = DateTime.Now.ToString("yyyyMMddHHmmss");
drFileInfo.EndEdit();
drFileInfo.AcceptChanges();
}
}
/**//// <summary>
/// Check url to get download file info
/// </summary>
/// <returns></returns>
private bool GetFileDownInfo()
...{
HttpWebRequest hwrq;
HttpWebResponse hwrp = null;
try
...{
//Create request
hwrq = (HttpWebRequest)WebRequest.Create(_fileInfo.RequestURL);
hwrp = (HttpWebResponse)hwrq.GetResponse();
//Get file size info
long L = hwrp.ContentLength;
L = ((L == -1) || (L > 0x7fffffff)) ? ((long)0x7fffffff) : L;
_fileInfo.TotalSize = (int)L;
_fileInfo.BlockLeftSize = _fileInfo.TotalSize;
//Check whether this url is supported to be multi-threads download
bool blnMulti = (hwrp.Headers["Accept-Ranges"] != null && hwrp.Headers["Accept-Ranges"] == "bytes");
hwrp.Close();//Close response here
return blnMulti;
}
catch (Exception e)
...{
throw e;
}
}
/**//// <summary>
/// Update download thread info
/// </summary>
/// <param name="ThreadNO"></param>
/// <param name="Position"></param>
/// <param name="DownloadSize"></param>
public void UpdateDownloadInfo(int ThreadNO, int Position, int DownloadSize)
...{
if (ThreadNO >= dtThreadInfo.Rows.Count)
...{
return;
}
DataRow drThreadNO = dtThreadInfo.Rows[ThreadNO];
drThreadNO["Position"] = Position + DownloadSize;
drThreadNO["BlockLeftSize"] = Convert.ToInt32(drThreadNO["BlockLeftSize"].ToString())
- DownloadSize;
drThreadNO.AcceptChanges();
drFileInfo["BlockLeftSize"] = Convert.ToInt32(drFileInfo["BlockLeftSize"].ToString()) - DownloadSize;
}
/**//// <summary>
/// Stop download threads
/// </summary>
public void Stop()
...{
for (int i = 0; i < subThreads.Length; i++)
...{
subThreads[i].Stop();
}
}
/**//// <summary>
/// Thread download finished
/// </summary>
private void DownloadFinished(object sender,EventArgs e)
...{
// Some download thread finished
nThreadFinishedCount++;
if (nThreadFinishedCount == subThreads.Length)
...{
// All download threads finished
if (drFileInfo != null)
...{
drFileInfo.Delete();
drFileInfo.AcceptChanges();
}
File.Move(_fileInfo.FileName + filenameExt, GetNewFilename(_fileInfo.FileName));
EventHandler handler = Finished;
if (handler != null)
...{
handler(this,EventArgs.Empty);
}
}
}
/**//// <summary>
/// 得到新名称
/// </summary>
/// <returns></returns>
public static string GetNewFilename(string filename)
...{
if (File.Exists(filename))
...{
string newname = filename;
int i = 0;
int lastPoint = filename.LastIndexOf('.');
do
...{
i++;
if (lastPoint < 1)
...{
newname = filename + "(" + i + ")";
}
else
...{
newname = filename.Substring(0, lastPoint) + "(" + i + ")" + filename.Substring(lastPoint);
}
}
while (File.Exists(newname));
return newname;
}
else
...{
return filename;
}
}
}
}