Hi I try to download resumeable ftp
I found http download class and work nice on http but I need ftp. can any body help me for add ftp support?
http class
Imports System.IO
Imports System.Net
Imports System.Threading
Public Class DownloadFileAsyncExtended
#Region "Methods"
Private _URL As String = String.Empty
Private _LocalFilePath As String = String.Empty
Private _userToken As Object = Nothing
Private _ContentLenght As Long = 0
Private _TotalBytesReceived As Integer = 0
Public Sub DowloadFileAsync(ByVal URL As String, ByVal LocalFilePath As String, ByVal userToken As Object)
Dim Request As HttpWebRequest
Dim fileURI As New Uri(URL)
If fileURI.Scheme <> Uri.UriSchemeHttp And fileURI.Scheme <> Uri.UriSchemeHttps Then
Throw New Exception("Invalid URL. Must be http:// or https://")
End If
_URL = URL
_LocalFilePath = LocalFilePath
_userToken = userToken
Request = CType(HttpWebRequest.Create(New Uri(URL)), HttpWebRequest)
Request.Credentials = Credentials
Request.AllowAutoRedirect = True
Request.ReadWriteTimeout = 30000
Request.Proxy = Proxy
Request.KeepAlive = False
Request.Headers = _Headers
If _ResumeAsync Then
Dim FileInfo As New FileInfo(LocalFilePath)
If FileInfo.Exists Then
Request.AddRange(FileInfo.Length)
End If
End If
_isbusy = True
_CancelAsync = False
Dim State As New HttpWebRequestState(LocalFilePath, Request, _ResumeAsync, userToken)
Dim result As IAsyncResult = Request.BeginGetResponse(AddressOf GetResponse_Callback, State)
ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, New WaitOrTimerCallback(AddressOf TimeoutCallback), State, 30000, True)
End Sub
Private Sub GetResponse_Callback(ByVal result As IAsyncResult)
Dim State As HttpWebRequestState = CType(result.AsyncState, HttpWebRequestState)
Dim DestinationStream As FileStream = Nothing
Dim Response As HttpWebResponse = Nothing
Dim Duration As New Stopwatch
Dim Buffer(8191) As Byte
Dim BytesRead As Integer = 0
Dim ElapsedSeconds As Integer = 0
Dim DownloadSpeed As Integer = 0
Dim DownloadProgress As Integer = 0
Dim BytesReceivedThisSession As Integer = 0
Try
Response = CType(State.Request.EndGetResponse(result), HttpWebResponse)
_ResponseHeaders = Response.Headers
If Response.StatusCode <> HttpStatusCode.OK And Response.StatusCode <> HttpStatusCode.PartialContent Then
OnDownloadCompleted(New FileDownloadCompletedEventArgs(New Exception(Response.StatusCode), False, State.userToken))
Return
End If
If State.ResumeDownload Then
DestinationStream = New FileStream(State.LocalFilePath, FileMode.OpenOrCreate, FileAccess.Write)
Else
DestinationStream = New FileStream(State.LocalFilePath, FileMode.Create, FileAccess.Write)
_ContentLenght = Response.ContentLength
End If
DestinationStream.Seek(0, SeekOrigin.End)
Duration.Start()
Using responseStream As Stream = Response.GetResponseStream()
Do
BytesRead = responseStream.Read(Buffer, 0, Buffer.Length)
If BytesRead > 0 Then
DestinationStream.Write(Buffer, 0, BytesRead)
_TotalBytesReceived += BytesRead
BytesReceivedThisSession += BytesRead
ElapsedSeconds = CInt(Duration.Elapsed.TotalSeconds)
Select Case ProgressUpdateFrequency
Case UpdateFrequency.NoDelay
If ElapsedSeconds > 0 Then
DownloadSpeed = (BytesReceivedThisSession \ ElapsedSeconds)
End If
OnDownloadProgressChanged(New FileDownloadProgressChangedEventArgs(_TotalBytesReceived, _ContentLenght, ElapsedSeconds, DownloadSpeed, State.userToken))
Case UpdateFrequency.HalfSecond
If (Duration.ElapsedMilliseconds - DownloadProgress) >= 500 Then
DownloadProgress = Duration.ElapsedMilliseconds
If ElapsedSeconds > 0 Then
DownloadSpeed = (BytesReceivedThisSession \ ElapsedSeconds)
End If
OnDownloadProgressChanged(New FileDownloadProgressChangedEventArgs(_TotalBytesReceived, _ContentLenght, ElapsedSeconds, DownloadSpeed, State.userToken))
End If
Case UpdateFrequency.Second
If (Duration.ElapsedMilliseconds - DownloadProgress) >= 1000 Then
DownloadProgress = Duration.ElapsedMilliseconds
If ElapsedSeconds > 0 Then
DownloadSpeed = (BytesReceivedThisSession \ ElapsedSeconds)
End If
OnDownloadProgressChanged(New FileDownloadProgressChangedEventArgs(_TotalBytesReceived, _ContentLenght, ElapsedSeconds, DownloadSpeed, State.userToken))
End If
End Select
If _CancelAsync Then Exit Do
End If
Loop Until BytesRead = 0
End Using
OnDownloadProgressChanged(New FileDownloadProgressChangedEventArgs(_TotalBytesReceived, _ContentLenght, Duration.Elapsed.TotalSeconds, DownloadSpeed, State.userToken))
If _CancelAsync Then
OnDownloadCompleted(New FileDownloadCompletedEventArgs(Nothing, True, State.userToken))
Else
OnDownloadCompleted(New FileDownloadCompletedEventArgs(Nothing, False, State.userToken))
End If
Catch ex As Exception
OnDownloadCompleted(New FileDownloadCompletedEventArgs(ex, False, State.userToken))
Finally
If DestinationStream IsNot Nothing Then
DestinationStream.Flush()
DestinationStream.Close()
DestinationStream = Nothing
End If
Duration.Reset()
Duration = Nothing
_isbusy = False
End Try
End Sub
Private Sub TimeoutCallback(ByVal State As Object, ByVal TimedOut As Boolean)
If TimedOut Then
Dim RequestState As HttpWebRequestState = CType(State, HttpWebRequestState)
If RequestState IsNot Nothing Then
RequestState.Request.Abort()
End If
End If
End Sub
Private _CancelAsync As Boolean = False
Public Sub CancelAsync()
_CancelAsync = True
End Sub
Private _ResumeAsync As Boolean = False
Public Sub ResumeAsync()
If _isbusy Then
Throw New Exception("Download is still busy. Use IsBusy property to check if download is already busy.")
End If
If String.IsNullOrEmpty(_URL) AndAlso String.IsNullOrEmpty(_LocalFilePath) Then
Throw New Exception("Cannot resume a download which hasn't been started yet. Call DowloadFileAsync first.")
Else
_ResumeAsync = True
DowloadFileAsync(_URL, _LocalFilePath, _userToken)
End If
End Sub
#End Region
#Region "Properties"
Public Enum UpdateFrequency
NoDelay = 0
HalfSecond = 1
Second = 2
End Enum
Public Property ProgressUpdateFrequency() As UpdateFrequency
Public Property Proxy() As IWebProxy
Public Property Credentials() As ICredentials
Public Property Headers() As New WebHeaderCollection
Private _isbusy As Boolean = False
Public ReadOnly Property IsBusy() As Boolean
Get
Return _isbusy
End Get
End Property
Private _ResponseHeaders As WebHeaderCollection = Nothing
Public ReadOnly Property ResponseHeaders() As WebHeaderCollection
Get
Return _ResponseHeaders
End Get
End Property
Private _synchronizingObject As System.ComponentModel.ISynchronizeInvoke
Public Property SynchronizingObject() As System.ComponentModel.ISynchronizeInvoke
Get
Return Me._synchronizingObject
End Get
Set(ByVal value As System.ComponentModel.ISynchronizeInvoke)
Me._synchronizingObject = value
End Set
End Property
#End Region
#Region "Events"
Public Event DownloadProgressChanged As EventHandler(Of FileDownloadProgressChangedEventArgs)
Private Delegate Sub DownloadProgressChangedEventInvoker(ByVal e As FileDownloadProgressChangedEventArgs)
Protected Overridable Sub OnDownloadProgressChanged(ByVal e As FileDownloadProgressChangedEventArgs)
If Me.SynchronizingObject IsNot Nothing AndAlso Me.SynchronizingObject.InvokeRequired Then
Me.SynchronizingObject.Invoke(New DownloadProgressChangedEventInvoker(AddressOf OnDownloadProgressChanged), _
New Object() {e})
Else
RaiseEvent DownloadProgressChanged(Me, e)
End If
End Sub
Public Event DownloadCompleted As EventHandler(Of FileDownloadCompletedEventArgs)
Private Delegate Sub DownloadCompletedEventInvoker(ByVal e As FileDownloadCompletedEventArgs)
Protected Overridable Sub OnDownloadCompleted(ByVal e As FileDownloadCompletedEventArgs)
If Me.SynchronizingObject IsNot Nothing AndAlso Me.SynchronizingObject.InvokeRequired Then
Me.SynchronizingObject.Invoke(New DownloadCompletedEventInvoker(AddressOf OnDownloadCompleted), _
New Object() {e})
Else
RaiseEvent DownloadCompleted(Me, e)
End If
End Sub
#End Region
End Class
Public Class HttpWebRequestState
Private _LocalFilePath As String
Private _Request As HttpWebRequest
Private _ResumeDownload As Boolean
Private _userToken As Object
Public Sub New(ByVal LocalFilePath As String, ByVal Request As HttpWebRequest, ByVal ResumeDownload As Boolean, ByVal userToken As Object)
_LocalFilePath = LocalFilePath
_Request = Request
_ResumeDownload = ResumeDownload
_userToken = userToken
End Sub
Public ReadOnly Property LocalFilePath() As String
Get
Return _LocalFilePath
End Get
End Property
Public ReadOnly Property Request() As HttpWebRequest
Get
Return _Request
End Get
End Property
Public ReadOnly Property ResumeDownload() As Boolean
Get
Return _ResumeDownload
End Get
End Property
Public ReadOnly Property userToken() As Object
Get
Return _userToken
End Get
End Property
End Class
Public Class FileDownloadProgressChangedEventArgs
Inherits System.EventArgs
Private _BytesReceived As Integer
Private _TotalBytesToReceive As Integer
Private _DownloadTime As Integer
Private _DownloadSpeed As Long
Private _userToken As Object
Public Sub New(ByVal BytesReceived As Integer, ByVal TotalBytesToReceive As Integer, ByVal DownloadTime As Integer, ByVal DownloadSpeed As Long, ByVal userToken As Object)
_BytesReceived = BytesReceived
_TotalBytesToReceive = TotalBytesToReceive
_DownloadTime = DownloadTime
_DownloadSpeed = DownloadSpeed
_userToken = userToken
End Sub
Public ReadOnly Property BytesReceived() As Integer
Get
Return _BytesReceived
End Get
End Property
Public ReadOnly Property TotalBytesToReceive() As Integer
Get
Return _TotalBytesToReceive
End Get
End Property
Public ReadOnly Property ProgressPercentage() As Integer
Get
If _TotalBytesToReceive > 0 Then
Return Math.Ceiling((_BytesReceived / _TotalBytesToReceive) * 100)
Else
Return -1
End If
End Get
End Property
Public ReadOnly Property DownloadTimeSeconds() As Integer
Get
Return _DownloadTime
End Get
End Property
Public ReadOnly Property RemainingTimeSeconds() As Integer
Get
If DownloadSpeedBytesPerSec > 0 Then
Return Math.Ceiling((_TotalBytesToReceive - _BytesReceived) / DownloadSpeedBytesPerSec)
Else
Return 0
End If
End Get
End Property
Public ReadOnly Property DownloadSpeedBytesPerSec() As Long
Get
Return _DownloadSpeed
End Get
End Property
Public ReadOnly Property userToken() As Object
Get
Return _userToken
End Get
End Property
End Class
Public Class FileDownloadCompletedEventArgs
Inherits System.EventArgs
Private _ErrorMessage As Exception
Private _Cancelled As Boolean
Private _userToken As Object
Public Sub New(ByVal ErrorMessage As Exception, ByVal Cancelled As Boolean, ByVal userToken As Object)
_ErrorMessage = ErrorMessage
_Cancelled = Cancelled
_userToken = userToken
End Sub
Public ReadOnly Property ErrorMessage() As Exception
Get
Return _ErrorMessage
End Get
End Property
Public ReadOnly Property Cancelled() As Boolean
Get
Return _Cancelled
End Get
End Property
Public ReadOnly Property userToken() As Object
Get
Return _userToken
End Get
End Property
End Class