How to use VB.NET from FTP Download Directory

I tried to download multiple directories from FTP server to my local machine,

I tried this,

Const localFile As String = "C:\Documents and Settings\cr\Desktop\T\New Folder\"
Const remoteFile As String = "textbox.Text"
Const host As String = "ftp://ftp.example.com"
Const username As String = "username"
Const password As String = "password"

For i1 = 0 To ListBox1 .SelectedItems.Count-1
Dim li As New ListViewItem
li = ListView1.Items.Add(ListBox1.SelectedItems(i1))
Dim URI1 As String = host + remoteFile & "/" & ListBox1.SelectedItems(i1)
Dim ftp1 As System.Net.FtpWebRequest = CType(FtpWebRequest.Create(URI1), FtpWebRequest)
ftp1.Credentials = New System.Net.NetworkCredential(username, password)
ftp1.KeepAlive = False
ftp1.UseBinary = True
ftp1.Method = System.Net.WebRequestMethods.Ftp.DownloadFile
Using response As System.Net.FtpWebResponse = CType( ftp1.GetResponse, System.Net.Ft pWebResponse)
Using responseStream As IO.Stream = response.GetResponseStream

Dim length As Integer = response.ContentLength
Dim bytes(length) As Byte

'loop to read & write to file
Using fs As New IO.FileStream(localFile & ListBox1.SelectedItems(i1), IO.FileMode.Create)
Dim buffer(2047) As Byte
Dim read As Integer = 1

Do
read = responseStream.Read(buffer, 0, buffer.Length)
fs.Write(buffer, 0, read)

Loop Until read = 0'see Note(1)
responseStream.Close()
fs.Flush()
fs.Close()
End Using
responseStream.Close()
End Using

response.Close()
End Using
li.BackColor = Color.Aquamarine
Next

But the problem is that I can download from the folder Multiple files, but unable to download subdirectories and their contents from the main directory.

Basically, the main directory consists of files and subdirectories. So is there any possible way to download subdirectories and their contents from FTP?

Thanks in advance.

For C# Download all files and subdirectories through FTP’s answer is translated into VB.NET:

FtpWebRequest does not have any explicit support for recursive file download (or any other recursive operation). You must implement recursion yourself:

>Column Out the remote directory
>Iterate the entries, download the files and recurse to the subdirectories (list them again, etc.)

One tricky part is to identify the files in the subdirectories. It cannot be done in a portable way using FtpWebRequest Up to this point. Unfortunately, FtpWebRequest does not support the MLSD command, which is the only portable way to retrieve a list of directories with file attributes in the FTP protocol. See also Checking if object on FTP server is file or directory.

Your choice is:

>Perform an operation on the file name, which will definitely fail on the file and succeed on the directory (or vice versa). That is, you can try to download the “name”. If Success, it is a file, if it fails, it is a directory.
>You may be lucky, in your specific case, you can tell the files in the directory by the file name (that is, all files have extensions, And subdirectories don’t)
> You use a long directory listing (LIST command = ListDirectoryDe​​​​​​​​​​​​​ The directory is identified by d. But many servers use different formats. The following example uses this method (assuming *nix format)

Sub DownloadFtpDirectory(
url As String, credentials As NetworkCredential, localPath As String )
Dim listRequest As FtpWebRequest = WebRequest.Create(url)
listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails
listReques t.Credentials = credentials

Dim lines As List(Of String) = New List(Of String)

Using listResponse As FtpWebResponse = listRequest.GetResponse(),
listStream As Stream = listResponse.GetResponseStream(),
listReader As StreamReader = New StreamReader(listStream)
While Not listReader.EndOfStream
lines.Add(listReader.ReadLine())
> End While
End Using

For Each line As String In lines
Dim tokens As String() =
line.Split(New Char() {" " }, 9, StringSplitOptions.RemoveEmptyEntries)
Dim name As String = tokens(8)
Dim permissions As String = tokens(0)

Dim localFilePath As String = Path.Combine (localPath, name)
Dim fileUrl As String = url + name

If permissions(0) = "d" Then
If Not Directory.Exists(localFilePath) Then
Directory.Create Directory(localFilePath)
End If
DownloadFtpDirectory(fileUrl + "/", credentials, localFilePath)
Else
Dim downloadRequest As FtpWebRequest = WebRequest.Create(fileUrl)
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile
downloadRequest.Credentials = credentials

Using downloadResponse As FtpWebResponse = downloadRequest.GetResponse(),
sourceStream As Stream = downloadResponse.GetResponseStream() ,
targetStream As Stream = File.Create(localFilePath)
Dim buffer As Byte() = New Byte(10240-1) {}
Dim read As Integer
Do
read = sourceStream.Read(buffer, 0, buffer.Length)
If read> 0 Then
targetStream.Write(buffer, 0, read)
End If
Loop Wh ile read> 0
End Using
End If
Next
End Sub

Use the following functions:

< pre>Dim credentials As NetworkCredential = New NetworkCredential(“user”, “mypassword”)
Dim url As String = “ftp://ftp.example.com/directory/to/download/”
DownloadFtpDirectory (url, credentials, “C:\target\directory”)

If you want to avoid the trouble of parsing the server-specific directory list format, please use the one that supports MLSD commands and/or parsing various LIST list formats Third-party libraries; and recursive downloading.

For example, using WinSCP .NET assembly, you can download the entire directory by calling Session.GetFiles once:

< /p>

' Setup session options
Dim SessionOptions As SessionOptions = New SessionOptions
With SessionOptions
.Protocol = Protocol.Ftp
.HostName = "ftp.example.com "
.UserName = "user"
.Password = "mypassword"
End With

Using session As Session = New Session()
'Connect
session.Open(SessionOptions)

'Download files
session.GetFiles("/directory/to/download/*", "C:\target\directory\*" ).C heck()
End Using

Internally, if the server supports it, WinSCP uses the MLSD command. If not, it uses the LIST command and supports many different list formats.

By default, the Session.GetFiles method is recursive.

(I am the author of WinSCP)

I tried Download multiple directories from FTP server to my local machine,

I tried this,

Const localFile As String = "C: \Documents and Settings\cr\Desktop\T\New Folder\"
Const remoteFile As String = "textbox.Text"
Const host As String = "ftp://ftp.example.com"< br />Const username As String = "username"
Const password As String = "password"

For i1 = 0 To ListBox1.SelectedItems.Count-1
Dim li As New ListViewItem
li = ListView1.Items.Add(ListBox1.SelectedItems(i1))
Dim URI1 As String = host + remoteFile & "/" & ListBox1.SelectedItems(i1)
Dim ftp1 As System.Net.FtpWebRequest = CType(FtpWebRequest.Create(URI1), FtpWebRequest)
ftp1.Credentials = New System.Net.NetworkCredential(username, password)
ftp1.KeepAlive = False
ftp1.UseBinary = True
f tp1.Method = System.Net.WebRequestMethods.Ftp.DownloadFile
Using response As System.Net.FtpWebResponse = CType(ftp1.GetResponse, System.Net.FtpWebResponse)
Using responseStream As IO.Stream = response .GetResponseStream

Dim length As Integer = response.ContentLength
Dim bytes(length) As Byte

'loop to read & write to file
Using fs As New IO.FileStream(localFile & ListBox1.SelectedItems(i1), IO.FileMode.Create)
Dim buffer(2047) As Byte
Dim read As Integer = 1

Do
read = responseStream.Read(buffer, 0, buffer.Length)
fs.Write(buffer, 0, read)

Loop Until read = 0'see Note (1)
responseStream.Close()
fs.Flush()
fs.Close()
End Using
responseStream.Close() End Using

response.Close()
End Using
li.BackColor = Color.Aquamarine
Next

But the problem is I can download multiple files from a folder, but cannot download subdirectories and their contents from the main directory.

Basically, the main directory consists of files and subdirectories. So is there any possible way to download from FTP Subdirectories and their contents?

Thanks in advance.

Translating my answer to C# Download all files and subdirectories through FTP into VB.NET:

FtpWebRequest does not have any explicit support for recursive file download (or any other recursive operation). You must implement recursion yourself:

>List remote directories
>Iterate entries, download files And recurse to subdirectories (list them again, etc.)

One tricky part is identifying files in subdirectories. This is not possible in a portable way using FtpWebRequest. Unfortunately, FtpWebRequest does not support MLSD Command, this is the only portable way to retrieve a directory listing with file attributes in the FTP protocol. See also Checking if object on FTP server is file or directory.

Your choice is:

> Perform an operation on the file name, the file name will definitely fail for the file and succeed for the directory (or vice versa). That is, you can try to download the “name”. If it succeeds, it is a file, if it fails, it is A directory.
>You may be lucky, in your specific case, you can tell the files in the directory by file name (i.e. all files have extensions, and subdirectories don’t)
>You use Long directory listings (LIST command = ListDirectoryDe​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ The following example uses this method (assuming *nix format)

Sub DownloadFtpDirectory(
url As String, credentials As NetworkCredential, localPath As String)
Dim listRequest As FtpWebRequest = WebRequest. Create(url)
listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails
listRequest.Credentials = credentials

Dim lines As Lis t(Of String) = New List(Of String)

Using listResponse As FtpWebResponse = listRequest.GetResponse(),
listStream As Stream = listResponse.GetResponseStream(),
listReader As StreamReader = New StreamReader(listStream)
While Not listReader.EndOfStream
lines.Add(listReader.ReadLine())
End While
End Using

For Each line As String In lines
Dim tokens As String() =
line.Split(New Char() {" "}, 9, StringSplitOptions.RemoveEmptyEntries)
Dim name As String = tokens(8)
Dim permissions As String = tokens(0)

Dim localFilePath As String = Path.Combine(localPath, name)
Dim fileUrl As String = url + name

If permissions(0) = "d" Then
If Not Directory.Exists(localFilePath) Then
Directory.CreateDirectory(localFilePath)
End If
DownloadFtpDirectory(fileUrl + "/", credentials, localFilePath)
Else
Dim downloadRequest As FtpWebRequest = WebRequest.Create(fileUrl)
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile
downloadRequest .Credentials = credentials

Using downloadResponse As FtpWebResponse = downloadRequest.GetResponse(),
sourceStream As Stream = downloadResponse.GetResponseStream(),
targetStream As Stream = File.Create(localFilePath )
Dim buffer As Byte() = New Byte(10240-1) {)
Dim read As Integer
Do
read = sourceStream.Read(buffer, 0, buffer. Length)
If read> 0 Then
targetStream.Write(buffer, 0, read)
End If
Loop While read> 0
End Using
End If
Next
End Sub

Use the following functions:

Dim credentials As NetworkCredential = New NetworkCredential("user", "mypassword ")
Dim url As String = "ftp://ftp.example.com/directory/to/download/"
DownloadFtpDirectory(url, credentials, "C:\target\directory")

If you want to avoid the trouble of parsing server-specific directory list formats, please use a third-party library that supports MLSD commands and/or parsing various LIST list formats; and recursive downloading.

For example , Using WinSCP .NET assembly, you can download the entire directory by calling Session.GetFiles once:

' Setup session options
Dim SessionOptions As SessionOptions = New SessionOptions
With SessionOptions
.Protocol = Protocol.Ftp
.HostName = "ftp.example.com"
.UserName = "user"
. Password = "mypassword"
End With

Using session As Session = New Session()
'Connect
session.Open(SessionOptions)

'Download files
session.GetFiles("/directory/to/download/*", "C:\target\directory\*").Check()
End Using

< p>Internally, if the server supports it, WinSCP uses the MLSD command. If not, it uses LIST command and supports many different list formats.

By default, the Session.GetFiles method is recursive.

(I am the author of WinSCP)

Leave a Comment

Your email address will not be published.