9 Replies - 442 Views - Last Post: 20 July 2014 - 05:38 AM Rate Topic: -----

#1 devdevil10  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 12-July 14

Download last modified file from ftp server

Posted 12 July 2014 - 11:03 AM

Hello all,

I am a vb.net newbie and I am trying to write a code that when executed pulls the latest file on an FTP server (based on creation date). So far, I've been able to list all the files in the remote directory. I know this can be done using regular expressions but unfortunately, I have no idea of how to implement that inside a code. So, any help is appreciated.

Regular expression to get the oldest file

(\d{2}-\d{2}-\d{2}\s{1,10}\d{2}:\d{2}\w{2})\s{1,21}(\d{1,10})\s{1,10}(.+)



My progress so far.

 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Dim ftpRequest As FtpWebRequest = DirectCast(WebRequest.Create("ftp://ftp.sitename.com/logs"), FtpWebRequest)

        ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails

        ftpRequest.Credentials = New NetworkCredential("username", "password")

        Dim ftpResponse As FtpWebResponse = DirectCast(ftpRequest.GetResponse(), FtpWebResponse)

        Dim ftpResponseStream As Stream = ftpResponse.GetResponseStream()

        Dim ftpReader As New StreamReader(ftpResponseStream)

        Console.WriteLine(ftpReader.ReadToEnd())

        MsgBox("Directory List Complete...!")

        ftpReader.Close()
        ftpResponse.Close()

    End Sub


Is This A Good Question/Topic? 0
  • +

Replies To: Download last modified file from ftp server

#2 andrewsw  Icon User is online

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3181
  • View blog
  • Posts: 10,659
  • Joined: 12-December 12

Re: Download last modified file from ftp server

Posted 12 July 2014 - 01:11 PM

What does the directory list look like?

I will mention that there is WebRequestMethods.Ftp.GetDateTimestamp as an option, but this is for an individual file. So, if the date/time from the directory list is reasonable to parse, then it is probably simpler to do so.
Was This Post Helpful? 0
  • +
  • -

#3 devdevil10  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 12-July 14

Re: Download last modified file from ftp server

Posted 13 July 2014 - 02:23 AM

View Postandrewsw, on 12 July 2014 - 01:11 PM, said:

What does the directory list look like?

I will mention that there is WebRequestMethods.Ftp.GetDateTimestamp as an option, but this is for an individual file. So, if the date/time from the directory list is reasonable to parse, then it is probably simpler to do so.


Thanks for the reply andrewsw. I am afraid WebRequestMethods.Ftp.GetDateTimestamp can only be used when the file name to be downloaded is known (I could be wrong though!). But I went on to try using regex and can't get the code to print output (the console.writeline does nothing) I don't receive any errors or anything. Just nothing happens. The output stream doesn't create the file either. So, I am assuming the problem to be within the regex or the way I am reading the responsestream for use with regex. If anyone can shed some light on what I am doing wrong and make some corrections, it would be great.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Dim ftpRequest As FtpWebRequest = DirectCast(WebRequest.Create("ftp://ftp.sitename.com/logs"), FtpWebRequest)

        ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails

        ftpRequest.Credentials = New NetworkCredential("username", "password")

        Dim ftpResponse As FtpWebResponse = DirectCast(ftpRequest.GetResponse(), FtpWebResponse)

        Dim ftpResponseStream As Stream = ftpResponse.GetResponseStream()

        Dim ftpReader As New StreamReader(ftpResponseStream)

        Dim result As String = ftpReader.ReadToEnd

        Dim pattern As String = "(\d{2}-\d{2}-\d{2}\s{1,10}\d{2}:\d{2}\w{2})\s{1,21}(\d{1,10})\s{1,10}(.+)"


            For Each match As Match In Regex.Matches(result, pattern)

                Console.WriteLine(match.Value())

                Dim output As IO.Stream

                ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile(match.Value)

            output = System.IO.File.Create("E:\new.zip")

                output.Close()

            Next

        MsgBox("Can't see sh*t!")

        ftpReader.Close()
        ftpResponse.Close()

    End Sub
P.S: I also tried to catch exceptions but there was none.

Was This Post Helpful? 0
  • +
  • -

#4 andrewsw  Icon User is online

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3181
  • View blog
  • Posts: 10,659
  • Joined: 12-December 12

Re: Download last modified file from ftp server

Posted 13 July 2014 - 04:58 AM

You still haven't shown us what the directory output looks like.
If we can't see the output how can we check the regex against this output?
Was This Post Helpful? 0
  • +
  • -

#5 devdevil10  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 12-July 14

Re: Download last modified file from ftp server

Posted 13 July 2014 - 05:32 AM

View Postandrewsw, on 13 July 2014 - 04:58 AM, said:

You still haven't shown us what the directory output looks like.
If we can't see the output how can we check the regex against this output?


Not sure what you mean by directory output. But if you meant the structure of the directory in the FTP server, here is a screenshot of it.

Posted Image
Was This Post Helpful? 0
  • +
  • -

#6 devdevil10  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 12-July 14

Re: Download last modified file from ftp server

Posted 16 July 2014 - 07:09 AM

I tried to use getdatetimstamp to get lastmodified file. But I received a 550 File or directory does not exist error. I even tried the webclient method. But the download links are contained inside a java script container which does not load when the script is executed. So, it also was a no go.

This post has been edited by andrewsw: 16 July 2014 - 10:12 AM
Reason for edit:: Removed previous quote, just press REPLY

Was This Post Helpful? 0
  • +
  • -

#7 ybadragon  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 177
  • View blog
  • Posts: 1,092
  • Joined: 11-May 12

Re: Download last modified file from ftp server

Posted 16 July 2014 - 09:34 AM

Are you able to get the number of files on the FTP site? If so can you then reference the file by index?

The way I did this at my last position was

1. Get the number of files on the FTP site and create a variable to hold and index and one for the latest date
2. create a loop from i = 0 to numFiles
3. within the loop I was able to do ftp.GetFile[i].LastModified, and if that last modified was later than the previous last modified date, store it, and store the index.
4. ftp.DownloadFile[index]

That is a very rough flow of how my programs went, also I was using Chilkat library for my ftp object
Was This Post Helpful? 1
  • +
  • -

#8 devdevil10  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 12-July 14

Re: Download last modified file from ftp server

Posted 17 July 2014 - 10:39 AM

Thanks ybadragon. Your answer was really helpful in figuring out how I could get the most recent file. But unfortunately, Chilkanet seems like a commercial product and I don't see any built in classes inside visual studio that supports counting of files before storing it to a variable. Any alternatives to achieve what I am trying to do?
Was This Post Helpful? 0
  • +
  • -

#9 devdevil10  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 12-July 14

Re: Download last modified file from ftp server

Posted 20 July 2014 - 05:08 AM

I was seeking help on another forum and a member there (cgeier) was kind enough to provide me with the solution. If anyone's interested, take a look at the attached files. Please note that my server stores file in the ascending order of last modified date. So, the last file in the FTP directory is always the latest file. This might not be the same case with other servers. Once again, thanks everyone for your helpful involvement in finding a solution to my problem.
Was This Post Helpful? 0
  • +
  • -

#10 devdevil10  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 12-July 14

Re: Download last modified file from ftp server

Posted 20 July 2014 - 05:38 AM

' FtpDownload.vb
'
' Subject: Download file using ftp.
'
' Description: This class contains the majority of the code
' that downloads a file from an ftp server. It searches
' for the newest file, and then downloads it.
'
' getFileFromFtpServerBW is for use with a BackgroundWorker
' and is the preferred way to download the file.
'
' getFileFromFtpServer is for use without a BackgroundWorker--
' it's use is not recommended.
'
' Notes: Values may be set using the constructor or the Properties.
'        _filenamePattern is already defined in this file and isn't
'        listed in the constructor. If necessary, it can be changed
'        using the Property "FilenamePattern"
'
' Written by:   cgeier 07/18/2014
' Modified by:  cgeier 07/19/2014    Changed getFileFromFtpServerBW
'                                    from a Sub to a Function.
'
'                                    Added and removed code from
'                                    getFileFromFtpServerBW so that 
'                                    exceptions are passed to e.Error
'                                    in RunWorkerCompleted for the
'                                    BackgroundWorker. Added code to
'                                    set value of state.percentDone
'           
'                                    Added code in getFileFromFtpServer
'                                    to reduce the number of times
'                                    Application.DoEvents is called.
'                                    Added exception handling.
'                                    Added code to show percent done.
'
'                                    Added additional comments.

Imports System.Text.RegularExpressions
Imports System.IO
Imports System.Net
Imports System.Threading
Imports System.ComponentModel

Public Class CurrentState
    Public status As String = String.Empty
    Public percentDone As Integer = 0

    'add any additional variables you want
    'to pass back to form
End Class

Public Class FtpDownload

    'Private _filenamePattern As String = "[-ldrwx]{10}\s+\d\s+\d\s+\d\s+\d+\s+(?<monthName>[A-Z][a-z]+)\s+(?<monthNumber>\d+)\s+(?<timeOfDay>\d{2}:\d{2})\s+(?<filenameDateYear>\d{4})-(?<filenameDateMonth>\d{2})-(?<filenameDateDay>\d{2})-(?<filenameTimePart>\d{4}).txt.tgz.*"
    'Private _filenamePattern As String = "[-ldrwx]{10}\s+\d\s+\d\s+\d\s+\d+\s+(?<monthName>[A-Z][a-z]+)\s+(?<monthNumber>\d+)\s+(?<timeOfDay>\d{2}:\d{2})\s+(?<filename>\d{4}-\d{2}-\d{2}-\d{4}.txt.tgz).*"
    'Private _filenamePattern As String = ".*(?<monthName>[A-Z][a-z]+)\s+(?<monthNumber>\d+)\s+(?<timeOfDay>\d{2}:\d{2})\s+(?<filename>\d{4}-\d{2}-\d{2}-\d{4}.txt.tgz).*"

    'works
    'Private _filenamePattern As String = ".*(?<filename>\d{4}-\d{2}-\d{2}-\d{4}.txt.tgz).*"

    'test
    Private _filenamePattern As String = ".*(?<filename>samba-\d.\d.\d+.tar.gz).*"

    Private _ftpRequest As FtpWebRequest = Nothing

    Private _downloadDirectory As String = String.Empty
    Private _ftpUrl As String = String.Empty
    Private _password As String = "user@name.com"
    Private _username As String = "anonymous"


    'Enum
    Private Enum FtpMethod
        ListFiles = 0
        Download = 1
    End Enum

    'Properties
    Public Property DownloadDirectory As String
        Get
            Return _downloadDirectory
        End Get

        Set(value As String)
            _downloadDirectory = value
        End Set
    End Property 'downloadDirectory

    Public Property FilenamePattern As String
        Get
            Return _filenamePattern
        End Get

        Set(value As String)
            _filenamePattern = value
        End Set
    End Property 'filenamePattern

    Public Property FtpUrl As String
        Get
            Return _ftpUrl
        End Get

        Set(value As String)
            _ftpUrl = value
        End Set
    End Property 'ftpUrl

    Public Property Password As String
        Get
            Return _password
        End Get

        Set(value As String)
            _password = value
        End Set
    End Property 'password

    Public Property Username As String
        Get
            Return _username
        End Get

        Set(value As String)
            _username = value
        End Set
    End Property 'username

    'constructor
    Public Sub New()

    End Sub

    Public Sub New(ByVal ftpUrl As String, _
                    ByVal username As String, _
                    ByVal password As String, _
                    ByVal downloadDirectory As String)

        _ftpUrl = ftpUrl
        _username = username
        _password = password
        _downloadDirectory = downloadDirectory

    End Sub

    Private Function getNewestFilename(ByVal directoryData As String) As String

        Dim output As String = String.Empty
        Dim lastFilename As String = String.Empty
        Dim newestFilename As String = String.Empty

        'create new instance of RegEx
        Dim myRegex As New Regex(_filenamePattern)

        'create new instance of Match
        Dim myMatch As Match = myRegex.Match(directoryData)

        'keep looking for matches until no more are found
        While myMatch.Success

            'get groups
            Dim myGroups As GroupCollection = myMatch.Groups

            'For Each groupName As String In myRegex.GetGroupNames
            'output += String.Format("Group: '{0}' Value: {1}", groupName, myGroups(groupName).Value)
            'output += System.Environment.NewLine
            'Next

            'Console.WriteLine(output)

            lastFilename = myGroups("filename").Value

            If Not String.IsNullOrEmpty(newestFilename) Then
                If lastFilename > newestFilename Then
                    newestFilename = lastFilename
                End If
            Else
                newestFilename = myGroups("filename").Value
            End If

            'Console.WriteLine("lastFilename: " + lastFilename + " newestFilename: " + newestFilename)


            'get next match
            myMatch = myMatch.NextMatch()
        End While

        If String.IsNullOrEmpty(newestFilename) Then
            newestFilename = "No filenames found using specified FilenamePattern."
        End If

        Return newestFilename
    End Function

    Private Function CreateFtpWebRequest(ByVal ftpUrl As String, ByVal username As String, ByVal password As String, ByVal ftpMethod As FtpMethod, ByVal keepAlive As Boolean) As Stream
        'Don't place any exception handling here
        'the error will get passed to the calling
        'sub/function

        'defined as Private
        '_ftpRequest = DirectCast(WebRequest.Create(New Uri(ftpUrl)), FtpWebRequest)
        _ftpRequest = WebRequest.Create(New Uri(ftpUrl))


        'either download the file or
        'list the files in the directory
        If ftpMethod = 0 Then
            'list files in directory
            _ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails
        ElseIf ftpMethod = 1 Then
            'download file
            _ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile
        End If

        'set username and password
        _ftpRequest.Credentials = New NetworkCredential(username, password)

        'return Stream
        Return _ftpRequest.GetResponse().GetResponseStream

    End Function

    Public Function getFileFromFtpServer() As String
        Dim loopCount As Integer = 0

        'set bufferSize to 256 kb
        Dim bufferSize As Integer = 256 * 1024

        'allocate buffer of bufferSize
        Dim buffer(bufferSize) As Byte

        'number of bytes read to buffer
        Dim bytesIn As Integer = 0


        Dim ftpResponseStream As Stream = Nothing
        Dim ftpReader As StreamReader = Nothing
        Dim directoryListing As String = String.Empty
        Dim filename As String = String.Empty
        Dim fqFilename As String = String.Empty
        Dim fileLength As Integer = 0
        Dim output As IO.Stream = Nothing
        Dim outputFilename As String = String.Empty
        Dim percentDoneDbl As Double = 0.0
        Dim percentDoneInt As Integer = 0

        'total bytes received
        Dim totalBytesIn As Integer = 0

        Dim errMsg As String = String.Empty

        If String.IsNullOrEmpty(_ftpUrl) Then
            errMsg = "FtpUrl not set."
            Throw New Exception(errMsg)
        End If

        If String.IsNullOrEmpty(_downloadDirectory) Then
            errMsg = "DownloadDirectory not set."
            Throw New Exception(errMsg)
        End If

        Try

            'create new request to get list of files
            'FtpMethod is an Enum created above
            ftpResponseStream = CreateFtpWebRequest(FtpUrl, Username, Password, FtpMethod.ListFiles, False)

            ftpReader = New StreamReader(ftpResponseStream)

            'get list of files
            directoryListing = ftpReader.ReadToEnd

            'close StreamReader
            ftpReader.Close()

            'close Stream
            ftpResponseStream.Close()

            'get newest filename
            filename = getNewestFilename(directoryListing)

            If filename.StartsWith("No filenames found") Then
                errMsg = filename
            End If

            If filename.Length > 0 And Not filename.StartsWith("No filenames found") Then

                'need to append filename to ftpUrl
                'in order to download the file

                If _ftpUrl.EndsWith("/") Then
                    fqFilename = FtpUrl + filename
                Else
                    fqFilename = FtpUrl + "/" + filename
                End If

                Console.WriteLine("fqFilename: " & fqFilename)

                'create new request to download fqFilename
                'FtpMethod is an Enum created above
                ftpResponseStream = CreateFtpWebRequest(fqFilename, Username, Password, FtpMethod.Download, True)

                'get file length
                fileLength = _ftpRequest.GetResponse().ContentLength

                Console.WriteLine("file length: " & fileLength)

                'file to save to
                If DownloadDirectory.EndsWith("\") Then
                    outputFilename = DownloadDirectory + filename
                Else
                    outputFilename = DownloadDirectory + "\" + filename
                End If

                'create filename on local computer
                output = System.IO.File.Create(outputFilename)

                Do
                    loopCount += 1

                    'read bytes to buffer
                    'and get actual # of bytes read
                    bytesIn = ftpResponseStream.Read(buffer, 0, bufferSize)

                    'Console.WriteLine("bytesIn: " & bytesIn)

                    If bytesIn > 0 Then
                        'write buffer to file
                        output.Write(buffer, 0, bytesIn)

                        totalBytesIn += bytesIn

                        percentDoneDbl = (Convert.ToDouble(totalBytesIn) / Convert.ToDouble(fileLength)) * 100.0
                        percentDoneInt = Convert.ToInt32(percentDoneDbl)

                        Console.WriteLine("Downloaded: " & totalBytesIn & " of " & fileLength & " (" & percentDoneInt & "%)")

                        'Prevent unresponsiveness.
                        'It is better to use the
                        'version that uses a BackgroundWorker.
                        'When using a BackgroundWorker, 
                        'Application.DoEvents() is not needed.
                        '
                        'Change 5 to an appropriate value for your code
                        'this will significantly reduce performance
                        'impact that occurs from calling ReportProgress 
                        'and checking cancellationPending too frequently.
                        '
                        'This makes it so that the code inside the if
                        'statement only runs every 5th iteration.
                        If loopCount Mod 5 = 0 Then
                            Application.DoEvents()
                        End If

                    End If
                Loop Until bytesIn < 1

            Else
                'Console.WriteLine(errMsg)
                Throw New Exception("No filenames found using specified FilenamePattern = " & _filenamePattern)
            End If

        Catch ex As WebException
            Console.WriteLine("Error: [getFileFromFtpServer]: " & ex.Message)
        Catch ex As Exception
            Console.WriteLine("Error: [getFileFromFtpServer]: " & ex.Message)
        Finally
            'make sure ftpReader is closed
            If Not ftpReader Is Nothing Then
                ftpReader.Close()
                ftpReader = Nothing
            End If

            'close output
            If Not output Is Nothing Then
                output.Close()
                output = Nothing
            End If

            'close ftpResponseStream
            If Not ftpResponseStream Is Nothing Then
                ftpResponseStream.Close()
                ftpResponseStream = Nothing
            End If

            buffer = Nothing
            _ftpRequest = Nothing
        End Try

        Return totalBytesIn.ToString()
    End Function

    Public Function getFileFromFtpServerBW(ByVal worker As BackgroundWorker, ByVal e As DoWorkEventArgs) As String

        Dim state As CurrentState = New CurrentState()
        Dim lastReportedDateTime As DateTime = DateTime.MinValue
        Dim loopCount As Integer = 0

        'set bufferSize to 256 kb
        Dim bufferSize As Integer = 256 * 1024

        'allocate buffer of bufferSize
        Dim buffer(bufferSize) As Byte

        'number of bytes read to buffer
        Dim bytesIn As Integer = 0

        Dim ftpResponseStream As Stream = Nothing
        Dim ftpReader As StreamReader = Nothing
        Dim directoryListing As String = String.Empty
        Dim filename As String = String.Empty
        Dim fqFilename As String = String.Empty
        Dim fileLength As Integer = 0
        Dim output As IO.Stream = Nothing
        Dim outputFilename As String = String.Empty
        Dim percentDoneDbl As Double = 0.0

        'total bytes received
        Dim totalBytesIn As Integer = 0

        Dim errMsg As String = String.Empty

        'check if FtpUrl and DownloadDirectory
        'values have been set
        If String.IsNullOrEmpty(_ftpUrl) Then
            errMsg = "FtpUrl not set."
            e.Cancel = True
        ElseIf String.IsNullOrEmpty(_downloadDirectory) Then
            errMsg = "DownloadDirectory not set."
            e.Cancel = True
        End If

        'exit if FtpUrl and/or DownloadDirectory
        'values have not been set
        If e.Cancel = True Then
            state.status = errMsg

            'report progress back to form
            worker.ReportProgress(0, state)

            'update last reported time
            lastReportedDateTime = DateTime.Now

            'if debugging, the debugger will 
            'stop here. Press F5 to continue
            'or Click "Debug", then select "Continue".
            '
            'This throws an exception that
            'will end up in e.Error in
            'BackgroundWorker2_RunWorkerCompleted
            Throw New Exception(errMsg)

            'exit function
            Return errMsg
        End If

        Try

            'create new request to get list of files
            'FtpMethod is an Enum created above
            ftpResponseStream = CreateFtpWebRequest(FtpUrl, Username, Password, FtpMethod.ListFiles, False)

            ftpReader = New StreamReader(ftpResponseStream)

            'get list of files
            directoryListing = ftpReader.ReadToEnd

            'close ftpReader
            ftpReader.Close()
            ftpReader = Nothing

            'close ftpResponseStream
            ftpResponseStream.Close()
            ftpResponseStream = Nothing

            'get newest filename
            filename = getNewestFilename(directoryListing)

            If filename.StartsWith("No filenames found") Then
                errMsg = filename
            End If

            If filename.Length > 0 And Not filename.StartsWith("No filenames found") Then

                'need to append filename to ftpUrl
                'in order to download the file
                fqFilename = FtpUrl + "/" + filename

                'Console.WriteLine("fqFilename: " & fqFilename)

                'create new request to download fqFilename
                'FtpMethod is an Enum created above
                ftpResponseStream = CreateFtpWebRequest(fqFilename, Username, Password, FtpMethod.Download, True)

                'get file length
                fileLength = _ftpRequest.GetResponse().ContentLength

                'Console.WriteLine("file length: " & fileLength)

                'file to save to
                If DownloadDirectory.EndsWith("\") Then
                    outputFilename = DownloadDirectory + filename
                Else
                    outputFilename = DownloadDirectory + "\" + filename
                End If

                'create filename on local computer
                output = System.IO.File.Create(outputFilename)

                Do
                    loopCount += 1

                    'change 9 to an appropriate value for your code
                    'this will significantly reduce performance
                    'impact that occurs from calling ReportProgress 
                    'and checking cancellationPending too frequently.
                    '
                    'This makes it so that the code inside the if
                    'statement only runs every 9th iteration.
                    If loopCount Mod 9 = 0 Then
                        If worker.CancellationPending Then
                            e.Cancel = True
                            Exit Do 'exit loop
                        End If

                        state.status = "Status: Downloaded " & totalBytesIn & " of " & fileLength
                        percentDoneDbl = (Convert.ToDouble(totalBytesIn) / Convert.ToDouble(fileLength)) * 100.0
                        state.percentDone = Convert.ToInt32(percentDoneDbl)

                        'report progress back to form
                        worker.ReportProgress(0, state)

                        'update last reported time
                        lastReportedDateTime = DateTime.Now
                    End If

                    'read bytes to buffer
                    'and get actual # of bytes read
                    bytesIn = ftpResponseStream.Read(buffer, 0, bufferSize)

                    'Console.WriteLine("bytesIn: " & bytesIn)

                    If bytesIn > 0 Then
                        'write buffer to file
                        output.Write(buffer, 0, bytesIn)

                        totalBytesIn += bytesIn

                        'Console.WriteLine("Downloaded: " & totalBytesIn & " of " & fileLength)

                    End If
                Loop Until bytesIn < 1

            Else
                'Console.WriteLine(errMsg)
                Throw New Exception("No filenames found using specified FilenamePattern = " & _filenamePattern)
            End If

            If e.Cancel = True Then
                state.status = "Status: Cancelled by user."
            Else
                state.status = "Status: Complete."
                percentDoneDbl = (Convert.ToDouble(totalBytesIn) / Convert.ToDouble(fileLength)) * 100.0
                state.percentDone = Convert.ToInt32(percentDoneDbl)
            End If

            'report progress back to form
            worker.ReportProgress(0, state)

            'update last reported time
            lastReportedDateTime = DateTime.Now

            'don't put any Catch statements here so
            'the errors will end up in e.Error in
            'BackgroundWorker2_RunWorkerCompleted
            'Handle the errors in 
            'BackgroundWorker2_RunWorkerCompleted

        Finally
            'make sure ftpReader is closed
            If Not ftpReader Is Nothing Then
                ftpReader.Close()
                ftpReader = Nothing
            End If

            'close output
            If Not output Is Nothing Then
                output.Close()
                output = Nothing
            End If

            'close ftpResponseStream
            If Not ftpResponseStream Is Nothing Then
                ftpResponseStream.Close()
                ftpResponseStream = Nothing
            End If

            buffer = Nothing
            _ftpRequest = Nothing
        End Try

        Return totalBytesIn.ToString()
    End Function

End Class



And the Module

' Module1.vb
'
' Subject: Download file using ftp.
'
' Description: Call "downloadFileBW" or 
' "downloadFile" to download
' the most recent file in the directory of the 
' server identified by ftpUrl.
'
' downloadFileBW uses a BackgroundWorker to 
' download the file--it is the preferred
' way to download the file.
'
' downloadFile downloads the file without
' using a BackgroundWorker--it's use
' is discouraged.
'
' Notes: Most variable values in FtpDownload can
' be set using either the constructor or the
' properties. _filenamePattern can only be changed
' by using the property "FilenamePattern"--not through
' the constructor
'
' Usage:
' downloadFileBW("ftp://ftp.server.com", "anonymous", "me@gmail.com", "C:\temp\")
'      or 
' downloadFileNoBW("ftp://ftp.server.com", "anonymous", "me@gmail.com", "C:\temp\")
'
' Written by:   cgeier 07/18/2014
' Modified by:  cgeier 07/19/2014   renamed downloadFile to downloadFileBW
'                                   added downloadFileNoBW

Imports System.Threading
Imports System.ComponentModel

Module Module1

    Private myFtpDownload As FtpDownload = Nothing
    Private cancelOperation As Boolean = False
    Private totalBytesDownloaded As Integer = 0
    Friend WithEvents BackgroundWorker2 As New BackgroundWorker


    Public Sub downloadFileNoBW(ByVal ftpUrl As String, ByVal username As String, ByVal password As String, ByVal downloadDirectory As String)
        myFtpDownload = New FtpDownload(ftpUrl, username, password, downloadDirectory)
        totalBytesDownloaded = myFtpDownload.getFileFromFtpServer()
        Console.WriteLine("Total Bytes Downloaded: " & totalBytesDownloaded)
    End Sub

    Public Sub downloadFileBW(ByVal ftpUrl As String, ByVal username As String, ByVal password As String, ByVal downloadDirectory As String)
        'reset cancelOperation
        cancelOperation = False

        'create new instance of FtpDownload
        'and setting values using the constructor
        'Alternatively, the following could be used:
        '
        'myFtpDownload = New FtpDownload()
        '
        'and the variables could be set using
        'the properties.
        '
        'ex: myFtpDownload.FtpUrl = "ftp://ftp.server.com"

        myFtpDownload = New FtpDownload(ftpUrl, username, password, downloadDirectory)

        'add support for cancellation and reporting progress
        BackgroundWorker2.WorkerSupportsCancellation = True
        BackgroundWorker2.WorkerReportsProgress = True

        If BackgroundWorker2.IsBusy <> True Then
            BackgroundWorker2.RunWorkerAsync(myFtpDownload)
        End If
    End Sub


    Private Sub BackgroundWorker2_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker2.DoWork
        Dim worker As BackgroundWorker
        worker = DirectCast(sender, BackgroundWorker)


        Dim myFtpDownload As FtpDownload = DirectCast(e.Argument, FtpDownload)

        'call getFileFromFtpServerBW
        totalBytesDownloaded = myFtpDownload.getFileFromFtpServerBW(worker, e)

        Console.WriteLine("Total Bytes Downloaded: " & totalBytesDownloaded)
    End Sub

    Private Sub BackgroundWorker2_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker2.ProgressChanged
        ' This event occurs every time
        ' "worker.ReportProgress(0, state)" is
        ' called in FtpDownload.getFileFromFtpServerBW

        Dim state As CurrentState = e.UserState
        Console.WriteLine(state.status & " (" & state.percentDone & "%)")
    End Sub

    Private Sub BackgroundWorker2_RunWorkerCompleted(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker2.RunWorkerCompleted
        If Not e.Error Is Nothing Then
            'Handle the errors here.
            'Write error message to console and/or
            'a log file.
            '
            'if using a Form, add a statusStrip. 
            'Then update StatusLabel here.

            Console.WriteLine("Error: " + e.Error.Message)
        ElseIf e.Cancelled = True Then
            'If using a Form, add a statusStrip. 
            'Then update StatusLabel here.
            Console.WriteLine("Cancelled by user.")
        Else
            'If using a Form, add a statusStrip. 
            'Then update StatusLabel here.
            Console.WriteLine("Successfully completed.")
        End If
    End Sub



End Module




All credits to cgeier for his work.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1