Link to home
Start Free TrialLog in
Avatar of yankeek
yankeekFlag for United States of America

asked on

FTP recursive download files

Experts -
I am needing vb.net code to point to an FTP root folder, find sub folders, and download any files that are in the sub folder(s).
I know that root folder name, but the sub folder name, and the file names in the sub folders are unknown. (They have date and time in the name so they are different every day.

Thanks!!
Ken
Avatar of Fernando Soto
Fernando Soto
Flag of United States of America image

Hi yankeek;

What code have you implemented, please post. Are you using FtpWebRequest if so these are the FTP commands that can be sent via the FTP web request method.
Avatar of yankeek

ASKER

Fernando,

I have tried various snippets I've found but nothing that does what I need. I can get directory listings, but because I don't know if the object listed is a file, or a folder, and the fact that the names change, I can't seem to sew them all in what I need.
Here is as close as I've got, but there is a problem on checking if the object is a file or a folder

Public Sub FTP_ListFiles(strURL As String)
        swOutput.WriteLine("FTP_ListFiles")
        Stop
        ' Get the object used to communicate with the server.
        Try
            Dim request As FtpWebRequest = DirectCast(WebRequest.Create(strAOC_FTP_Site), FtpWebRequest)
            request.Method = WebRequestMethods.Ftp.ListDirectory
            request.EnableSsl = True
            request.UsePassive = True

            ' The following line forces this program to accept a cert, even when it's not there.
            ServicePointManager.ServerCertificateValidationCallback = Function(s As Object, certificate As X509Certificate, chain As X509Chain, sslPolicyErrors As SslPolicyErrors) True
            ' Login and read what is in the remote directory.
            request.Credentials = New NetworkCredential(strUserID, strPass)
            Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
            Dim responseStream As Stream = response.GetResponseStream()
            Dim reader As New StreamReader(responseStream)


            Dim lstFTPObjects As New List(Of String)
            Dim x As Int16 = 0
            Do Until strFTPObject Is Nothing
                strFTPObject = reader.ReadLine()
                If strFTPObject Is Nothing Then Exit Do
                lstFTPObjects.Add(strFTPObject)
                Console.WriteLine(lstFTPObjects(x))
                x += 1
                Dim credentials As New NetworkCredential(strUserID, strPass)
                Stop
                If IsFile(strURL) = True Then
                    Call DownloadFile(strURL, strLocal_File_Location)
                Else
                    ' If we have a folder, add to the URL and call this sub again
                    strURL += "/" & strFTPObject

                    Call FTP_ListFiles(strURL)
                End If
            Loop
            ' Display the FTP status
            Console.WriteLine("Directory List Complete, status {0}", response.StatusDescription)
            reader.Close()
            response.Close()
        Catch ex As Exception
            swOutput.WriteLine(ex.Message)
            Console.WriteLine(ex.Message)
        End Try
    End Sub

Take close note on this function. It hangs the program on 2nd call

Public Function IsFile(ftpPath As String) As Boolean
        Stop
        'Dim request = DirectCast(WebRequest.Create(ftpPath), FtpWebRequest)
        Dim request As FtpWebRequest = DirectCast(WebRequest.Create(ftpPath), FtpWebRequest)
        request.Method = WebRequestMethods.Ftp.GetFileSize
        request.Credentials = New NetworkCredential(strUserID, strPass)
        request.EnableSsl = True
        request.UsePassive = True
        request.KeepAlive = False

        Try
            ' The following line causes the program to halt on 2nd time FTP_ListFiles calls itself with the new URL path
            Using response = DirectCast(request.GetResponse(), FtpWebResponse)
                Using responseStream = response.GetResponseStream()
                    Console.WriteLine("It is a FILE")
                    Return True
                End Using
            End Using
        Catch ex As WebException
            Console.WriteLine("It is a DIRECTORY")
            Return False
        End Try

    End Function
ASKER CERTIFIED SOLUTION
Avatar of Fernando Soto
Fernando Soto
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of yankeek

ASKER

I basically found that works. I check for "<DIR>" within the record, and then add that name to the path.

Thanks