www.pudn.com > SharpDownload(FTP¼°WEBÏÂÔØ).zip > FilePart.cs
using System;
using System.Diagnostics;
using System.Threading;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
namespace SharpDownload
{
///
/// The file part class handles individual part downloads.
/// It initiates connections with servers and manages data downloading.
///
public class FilePart
{
private string sourceFile;
private string destinationFile;
private long byteOffset;
private long partSize;
private long bytesDownloaded;
private int partNumber;
private ProtocolClient protocolClient;
private bool downloadComplete = false;
private bool isLastPart = false;
private FileDownload.FileDownloadCommandEnum command = FileDownload.FileDownloadCommandEnum.NoCommand;
private const string MODULE_NAME = "FilePart";
///
/// Default constructor
///
/// The number of this part within the File Download
public FilePart(int PartNumber)
{
this.partNumber = PartNumber;
}
///
/// Byte offset property
///
public long ByteOffset
{
get
{
return byteOffset;
}
set
{
byteOffset = value;
}
}
///
/// Part size property
///
public long PartSize
{
get
{
return partSize;
}
set
{
partSize = value;
}
}
///
/// Bytes downloaded property
///
public long BytesDownloaded
{
get
{
return bytesDownloaded;
}
set
{
bytesDownloaded = value;
}
}
///
/// Protocol client used for downloading and comms
///
public ProtocolClient ProtocolClient
{
get
{
return protocolClient;
}
}
///
/// Source file to download
///
public string SourceFile
{
get
{
return sourceFile;
}
set
{
sourceFile=value;
}
}
///
/// Destination file to download to
///
public string DestinationFile
{
get
{
return destinationFile;
}
set
{
destinationFile=value;
}
}
///
/// The part number of the File Download
///
public int PartNumber
{
get
{
return partNumber;
}
set
{
partNumber = value;
}
}
///
/// Flag to mark the download as completed
///
public bool IsDownloadComplete
{
get
{
return downloadComplete;
}
}
///
/// Flag if this part is the last part
///
public bool IsLastPart
{
get
{
return isLastPart;
}
set
{
isLastPart = value;
}
}
public FileDownload.FileDownloadCommandEnum Command
{
get
{
return command;
}
set
{
command = value;
// Set the protocol client value as well
if (protocolClient!=null)
{
protocolClient.Command = value;
}
}
}
///
/// Asynchronous download call
///
/// DownloadInfo component
/// true if download started; false otherwise
public bool AsyncDownload(DownloadInfo downloadInfo)
{
// Call factory create
protocolClient = ProtocolClient.GetProtocolClient(downloadInfo);
// Set up the event handlers
protocolClient.DownloadStartedEvent += new ProtocolClient.DownloadStartedEventHandler(PartDownloadStarted);
protocolClient.DataReceivedEvent += new ProtocolClient.DataReceivedEventHandler(PartDataReceived);
// Start the transfer
protocolClient.BeginDownload(this.SourceFile, this.DestinationFile, downloadInfo.ResumeSupported, this.ByteOffset, this.PartSize, this.PartSize, this.IsLastPart, new AsyncCallback(PartDownloadFinished));
return true;
}
#region PartDownloadStarted Event
///
/// Part download started event arguments
///
public class PartDownloadStartedEventArgs : EventArgs
{
private readonly int partNumber;
///
/// PartDownloadStarted event arguments
///
/// Size of the file in Bytes
public PartDownloadStartedEventArgs (int PartNumber)
{
partNumber = PartNumber;
}
///
/// Public read-only size of the file in Bytes
///
public int PartNumber
{
get
{
return partNumber;
}
}
}
///
/// Delegate for Part Download Started Event
///
public delegate void PartDownloadStartedEventHandler(FilePart sender, PartDownloadStartedEventArgs e);
///
/// The Part Download Started Event is raised when the download starts
///
public event PartDownloadStartedEventHandler PartDownloadStartedEvent;
///
/// OnPartDownloadStartedEvent
///
/// PartDownloadStartedEventArgs
protected virtual void OnPartDownloadStartedEvent(PartDownloadStartedEventArgs e)
{
// Check if any events have been bound
if (PartDownloadStartedEvent != null)
{
PartDownloadStartedEvent(this, e);
}
}
#endregion
#region PartDownloadStatus Event
///
/// Part download statuses
///
public enum PartDownloadStatusEnum
{
///
/// The file part is initialising
///
Initialising,
///
/// The file part has completed initialising
///
Initialised,
///
/// The file part is logging in to the server
///
LoggingIn,
///
/// The file part has logged in
///
LoggedIn,
///
/// The file part is currently receiving data
///
ReceivingFile,
///
/// The file part has finished receiving
///
FileReceived,
///
/// The file part is closing
///
Closing,
///
/// The file part has closed
///
Closed
}
///
/// Part download status event arguments
///
public class PartDownloadStatusEventArgs : EventArgs
{
private PartDownloadStatusEnum partDownloadStatus;
///
/// PartDownloadStatus event arguments
///
/// Current part download status
public PartDownloadStatusEventArgs (PartDownloadStatusEnum currentPartDownloadStatus)
{
partDownloadStatus = currentPartDownloadStatus;
}
///
/// Public read-only property returns the download status
///
public PartDownloadStatusEnum PartDownloadStatus
{
get
{
return partDownloadStatus;
}
}
}
///
/// Delegate for Part Download Started Event
///
public delegate void PartDownloadStatusEventHandler(FilePart sender, PartDownloadStatusEventArgs e);
///
/// The Part Download Started Event is raised when the download starts
///
public event PartDownloadStatusEventHandler PartDownloadStatusEvent;
///
/// OnPartDownloadStatusEvent
///
/// PartDownloadStatusEventArgs
protected virtual void OnPartDownloadStatusEvent(PartDownloadStatusEventArgs e)
{
// Check if any events have been attached
if (PartDownloadStatusEvent != null)
{
PartDownloadStatusEvent(this, e);
}
}
#endregion
#region PartDataReceived Event
///
/// Part data received event arguments
///
public class PartDataReceivedEventArgs : EventArgs
{
private readonly long totalPartDataReceived;
///
/// Default constructor
///
/// Total amount of data in bytes received
public PartDataReceivedEventArgs (long totalPartData)
{
this.totalPartDataReceived = totalPartData;
}
///
/// Read-only param to get the total number of bytes received
///
public long TotalDataReceived
{
get
{
return totalPartDataReceived;
}
}
}
///
/// Delegate for Data Received Event
///
public delegate void PartDataReceivedEventHandler(FilePart sender, PartDataReceivedEventArgs e);
///
/// The Data Received Event is raised when data is received in the download module.
///
public event PartDataReceivedEventHandler PartDataReceivedEvent;
///
/// OnPartDataReceivedEvent
///
/// PartDataReceivedEventArgs
protected virtual void OnPartDataReceivedEvent(PartDataReceivedEventArgs e)
{
// Check if any events have been attached
if (PartDataReceivedEvent != null)
{
PartDataReceivedEvent(this, e);
}
}
#endregion
#region PartDownloadStopped Event
///
/// Part download stopped event arguments
///
public class PartDownloadStoppedEventArgs : EventArgs
{
private ProtocolClient.DownloadResult downloadResult;
///
/// Public default constructor
///
public PartDownloadStoppedEventArgs (ProtocolClient.DownloadResult Result)
{
downloadResult = Result;
}
public ProtocolClient.DownloadResult Result
{
get
{
return downloadResult;
}
}
}
///
/// Delegate for Part Download Started Event
///
public delegate void PartDownloadStoppedEventHandler(FilePart sender, PartDownloadStoppedEventArgs e);
///
/// The Part Download Started Event is raised when the download starts
///
public event PartDownloadStoppedEventHandler PartDownloadStoppedEvent;
///
/// OnPartDownloadStoppedEvent
///
/// PartDownloadStoppedEventArgs
protected virtual void OnPartDownloadStoppedEvent(PartDownloadStoppedEventArgs e)
{
// Check if any events have been attached
if (PartDownloadStoppedEvent != null)
{
PartDownloadStoppedEvent(this, e);
}
}
#endregion
#region PartDownloadFinished Event
///
/// Part download started event arguments
///
public class PartDownloadFinishedEventArgs : EventArgs
{
///
/// Public default constructor
///
public PartDownloadFinishedEventArgs ()
{
}
}
///
/// Delegate for Part Download Started Event
///
public delegate void PartDownloadFinishedEventHandler(FilePart sender, PartDownloadFinishedEventArgs e);
///
/// The Part Download Started Event is raised when the download starts
///
public event PartDownloadFinishedEventHandler PartDownloadFinishedEvent;
///
/// OnPartDownloadFinishedEvent
///
/// PartDownloadFinishedEventArgs
protected virtual void OnPartDownloadFinishedEvent(PartDownloadFinishedEventArgs e)
{
// Check if any events have been attached
if (PartDownloadFinishedEvent != null)
{
PartDownloadFinishedEvent(this, e);
}
}
#endregion
#region Event handlers
// Part download started event handler
private void PartDownloadStarted(ProtocolClient sender, ProtocolClient.DownloadStartedEventArgs e)
{
try
{
OnPartDownloadStartedEvent(new PartDownloadStartedEventArgs(this.PartNumber));
}
catch (Exception ePartDownloadStartedEvent)
{
Debug.WriteLine("Exception occurred in PartDownloadStarted [" + ePartDownloadStartedEvent.Message + "]", MODULE_NAME);
}
}
// Data received event handler
private void PartDataReceived(ProtocolClient sender, ProtocolClient.DataReceivedEventArgs e)
{
try
{
this.BytesDownloaded = e.TotalDataReceived;
OnPartDataReceivedEvent(new PartDataReceivedEventArgs(this.BytesDownloaded));
}
catch (Exception ePartDataReceivedEvent)
{
Debug.WriteLine("Exception occurred in PartDataReceived [" + ePartDataReceivedEvent.Message + "]", MODULE_NAME);
}
}
// Download finished callback
private void PartDownloadFinished(IAsyncResult result)
{
try
{
// Check the callback result
AsyncResult aResult = (AsyncResult)result;
ProtocolClient.DownloadFileNameFileNameResumeOffsetStopAtFileSizeLastPartCallback asyncDelegate = (ProtocolClient.DownloadFileNameFileNameResumeOffsetStopAtFileSizeLastPartCallback)aResult.AsyncDelegate;
ProtocolClient.DownloadResult returnVal = asyncDelegate.EndInvoke(aResult);
Debug.WriteLine("PartDownloadFinished callback, result was: " + returnVal, MODULE_NAME + "[" + this.PartNumber.ToString() + "]");
if (this.PartSize!=this.BytesDownloaded) Debug.WriteLine("WARNING - file part size mismatch [" + this.BytesDownloaded + " bytes, expected " + this.PartSize + " bytes]", MODULE_NAME + "[" + this.PartNumber + "]");
// Close the client
ProtocolClient protocolClientReturned = (ProtocolClient)result.AsyncState;
if ( protocolClientReturned != null ) protocolClientReturned.Close();
protocolClientReturned = null;
// Check the return value
switch (returnVal)
{
case ProtocolClient.DownloadResult.Finished:
// Set the download to completed
this.downloadComplete = true;
// Raise the download finished event
OnPartDownloadFinishedEvent(new PartDownloadFinishedEventArgs());
break;
case ProtocolClient.DownloadResult.Error:
// Set the download to NOT completed
this.downloadComplete = false;
OnPartDownloadStoppedEvent(new PartDownloadStoppedEventArgs(returnVal));
break;
case ProtocolClient.DownloadResult.Cancelled:
// Set the download to NOT completed
this.downloadComplete = false;
// Raise the download cancelled event
OnPartDownloadStoppedEvent(new PartDownloadStoppedEventArgs(returnVal));
break;
case ProtocolClient.DownloadResult.Paused:
// Set the download to NOT completed
this.downloadComplete = false;
// Raise the download cancelled event
OnPartDownloadStoppedEvent(new PartDownloadStoppedEventArgs(returnVal));
break;
default:
break;
}
}
catch (Exception e)
{
// Log the error
Debug.WriteLine("An error occurred while downloading the file. [" + e.Message + "]", MODULE_NAME);
}
}
#endregion
}
}