using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
namespace RtftClient
{
class HttpDownloader
{
private Uri m_url = null;
private string m_savePath = string.Empty;
public event System.Threading.WaitCallback ProgressChanged;
public event System.Threading.WaitCallback Closed;
private WebRequest m_request = null;
private WebResponse m_response = null;
private bool m_cancel = false;
public Uri URL
{
set
{
m_url = value;
}
}
public string SavePath
{
set
{
m_savePath = value;
}
}
public void Cancel()
{
m_cancel = true;
}
public long Start()
{
m_cancel = false;
if(m_url == null)
{
throw(new System.ArgumentException("url is invalid."));
}
if (string.IsNullOrEmpty(m_savePath))
{
throw (new System.ArgumentException("savepath is invalid."));
}
HttpWebRequest m_request = (HttpWebRequest)WebRequest.Create(m_url);
m_request.Method = "get";
m_response = (HttpWebResponse)m_request.GetResponse();
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(DownLoad), m_response);
return m_response.ContentLength;
}
private void DownLoad(object response)
{
CloseState closeState = new CloseState();
Stream rps = m_response.GetResponseStream();
FileStream fs = new FileStream(m_savePath, FileMode.Create, FileAccess.ReadWrite);
using (rps)
{
using (fs)
{
try
{
int retrycount = 0;
byte[] buffer = new byte[4096];
long receivecount = 0;
int readcount = 0;
while (true)
{
reTry:
try
{
readcount = rps.Read(buffer, 0, buffer.Length);
}
catch (System.Exception ex)
{
if (retrycount++ <= 3)
{
goto reTry;
}
else
{
closeState.CloseType = CloseType.Exception;
closeState.Memo = ex.Message;
break;
}
}
if (m_cancel)
{
closeState.CloseType = CloseType.Cancel;
closeState.Memo = string.Empty;
break;
}
if (readcount > 0)
{
fs.Write(buffer, 0, readcount);
receivecount += readcount;
ProgressChanged(receivecount);
if (receivecount >= m_response.ContentLength)
{
break;
}
}
}
}
catch (System.Exception ex)
{
closeState.CloseType = CloseType.Exception;
closeState.Memo = ex.Message;
}
finally
{
Closed(closeState);
}
}
}
}
}
public class CloseState
{
public CloseType CloseType = CloseType.Normal;
public string Memo = string.Empty;
}
public enum CloseType
{
Normal,
Cancel,
Exception
}
}