
ne of the features released with the 2.0 version of .NET was support for FTP. In .NET 2.0, you can now programmatically access FTP servers using the FtpWebRequest and FtpWebResponse managed classes (both derived from the WebRequest and WebResponse classes).
To illustrate the usefulness of using FTP in your .NET applications, I will build a Photo Viewer Windows application that accesses an FTP server. Using this application, users can upload photos to an FTP server and at the same time view images stored on the FTP server. This application is useful to companies who may need to access images uploaded by its partners. A good example is insurance companies, who may need to view photographs of car damages taken by workshop mechanics in order to estimate the cost of repair. Rather than build a complex Web application, the workshop and insurance companies can simply use this application to quickly upload and view photos.
Figure 1 shows what the application will look like when completed.
Creating the Application
Using Visual Studio 2005, create a new Windows application and name it PhotoViewer. Populate the default Form1 with the controls shown in Figure 2. The controls are:
- Button
- GroupBox
- Label
- PictureBox
- TextBox
- ToolStripStatusLabel
- TreeView
The TreeView control is used to display the directory structure of the FTP server.

Figure 1. The completed Photo Viewer application.
|
|

Figure 2. Populate Form1 with the various controls shown. |
Besides those listed above, you'll also need to add an ImageList control to Form1 to contain three images representing an opened folder, a closed folder, and an image file. You can specify these images by specifying them in the control's Image property (see Figure 3).
You also need to associate the ImageList control with the TreeView control by specifying ImageList1 in the ImageList property of the TreeView control (TreeView1).
Building the Directory Tree and Displaying Images
Switching to the code-behind of Form1, import the following namespaces:
Imports System.Net
Imports System.IO
Declare the following constants and member variables:
Public Class Form1
'---FTP server---
Const ftpServer As String = "ftp://127.0.0.1"
'---constants for the icon images---
Const icoOpen = 0
Const icoClose = 1
Const icoPhoto = 2
'---login credentials for the FTP server---
Private Username As String = "anonymous"
Private Password As String = "password"
When the form is loaded, display a node representing the root directory:
Private Sub Form1_Load( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
Try
'—-create the root node for the TreeView—-
Dim node As New TreeNode
node.ImageIndex = icoClose
node.SelectedImageIndex = icoOpen
node.Text = "/"
'---add the root node to the control---
TreeView1.Nodes.Add(node)
'—-add the dummy child node to the root node—-
node.Nodes.Add("")
'---select the root node---
TreeView1.SelectedNode = node
Catch err As Exception
MsgBox(err.ToString)
End Try
End Sub
Note that I add a dummy node after each node is created. This is to ensure that the current node can be expanded to reveal subdirectories (even if there are none). This is shown in
Figure 4.
 | |
Figure 3. Add three images to the ImageList control. |
When a node is expanded (by clicking on the "+" symbol), the TreeView1_BeforeExpand event is called. You have to write code that checks to see if the current node is a leaf node (meaning it is not a directory, but a file). If it is a leaf node, exit the method. Otherwise you need to display its sub-directories (if any).
You should also change the current node icon to "open" if the node is selected and "closed" if the node is not selected. Below is the code for expanding folders and displaying the proper icon at each node:
Private Sub TreeView1_BeforeExpand( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) _
Handles TreeView1.BeforeExpand
'---if leaf node (photo) then exit---
If e.Node.ImageIndex = icoPhoto Then Return
'---remove the dummy node and display
' the subdirectories and files---
Try
'---clears all the nodes and...---
e.Node.Nodes.Clear()
'---create the nodes again---
BuildDirectory(e.Node)
Catch err As Exception
ToolStripStatusLabel1.Text = err.ToString
End Try
'---change the icon for this node to open---
If e.Node.GetNodeCount(False) > 0 Then
e.Node.ImageIndex = icoClose
e.Node.SelectedImageIndex = icoOpen
End If
End Sub
The
BuildDirectory() subroutine displays all the files and subdirectories within the current directory in the TreeView control. Before I look at the definition of the
BuildDirectory() subroutine, I'll define the
GetDirectoryListing() function, whose main job it is to request from the FTP server the directory listing of a particular path:
'---Get the file/dir listings and return them as a string array---
Private Function GetDirectoryListing(ByVal path As String) _
As String()
Try
Dim ftpReq As FtpWebRequest = WebRequest.Create(path)
ftpReq.Method = WebRequestMethods.Ftp.ListDirectoryDetails
ftpReq.Credentials = New NetworkCredential( _
Username, Password)
Dim FTPResp As FtpWebResponse = ftpReq.GetResponse
Dim ftpRespStream As Stream = FTPResp.GetResponseStream
Dim reader As StreamReader
reader = New StreamReader( _
ftpRespStream, System.Text.Encoding.UTF8)
'---obtain the result as a string array---
Dim result() As String = reader.ReadToEnd.Split(vbLf)
FTPResp.Close()
Return result
Catch ex As Exception
MsgBox(ex.ToString)
Return Nothing
End Try
End Function
 | |
Figure 4. Add a dummy node to a node so that it can be expanded. |
To view the directory listing of an FTP server:
- Create an instance of the FtpWebRequest class using the Create() method of the WebRequest class. The Create() method takes in a URI parameter (containing the full FTP path).
- Set the command to be sent to the FTP server using the Method property of the FtpWebRequest class; in this case the command is ListDirectoryDetails.
- Specify the login credential to the FTP server.
- Obtain the response from the FTP server using the GetResponse() method from the FtpWebRequest class.
- Retrieve the stream that contains response data sent from an FTP server using the GetResponseStream() method from the FtpWebResponse class.
- You can use a StreamReader object to read the directory listing.
The directory listings are each separated by a LineFeed (vbLf) character. If your FTP server is configured with MS-DOS directory listing style (see
Figure 5), the directory listing looks something like this:
12-11-06 10:54PM 2074750 DSC00098.JPG
12-11-06 10:54PM 2109227 DSC00099.JPG
12-11-06 10:49PM <DIR> George
12-11-06 10:49PM <DIR> James
12-11-06 10:58PM <DIR> Wei-Meng Lee
Author's Note: For this article, I am using the FTP service available in Windows XP. Also note that you need to give write permission to users so that they can create new directories and upload files to the FTP server. |
As all subdirectories have the <DIR> field, you can simply differentiate subdirectories from files in the BuildDirectory() subroutine by looking for the "<DIR>" words:
'---Build the directory in the TreeView control---
Private Sub BuildDirectory(ByVal ParentNode As TreeNode)
Dim listing() As String = _
GetDirectoryListing(ftpServer & ParentNode.FullPath)
For Each line As String In listing
If line = String.Empty Then Exit For
Dim node As New TreeNode
If line.Substring(24, 5) = "" Then
'---this is a directory---
'---create a new node to be added---
With node
.Text = line.Substring(39)
.ImageIndex = icoClose
.SelectedImageIndex = icoOpen
'---add the dummy child node---
.Nodes.Add("")
End With
ParentNode.Nodes.Add(node)
Else
'---this is a normal file---
'---create a new node to be added---
With node
.Text = line.Substring(39)
.ImageIndex = icoPhoto
.SelectedImageIndex = icoPhoto
End With
ParentNode.Nodes.Add(node)
End If
Next
End Sub
When a node is selected, you first obtain the current path of the node and then display its path in the status bar if it is a folder. If it is an image node, download and display the photo using the
DownloadImage() subroutine:
Private Sub TreeView1_AfterSelect( _
ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.TreeViewEventArgs) _
Handles TreeView1.AfterSelect
'---always ignore the first "/" char---
Dim FullPath As String = _
ftpServer & e.Node.FullPath.Substring(1).Replace(vbCr, "")
'---display the current folder selected---
If e.Node.ImageIndex <> icoPhoto Then
ToolStripStatusLabel1.Text = FullPath
Return
End If
'---download image---
DownloadImage(FullPath)
End Sub
 | |
Figure 5. Choose the directory listing style of the FTP server, in this case MS-DOS. |
The
DownloadImage() subroutine downloads an image from the FTP server and displays the image in a PictureBox control:
'---Download the image from the FTP server---
Private Sub DownloadImage(ByVal path As String)
Try
Dim filename As String = path
Dim ftpReq As FtpWebRequest = WebRequest.Create(filename)
ftpReq.Method = WebRequestMethods.Ftp.DownloadFile
ftpReq.Credentials = New NetworkCredential( _
Username, Password)
ToolStripStatusLabel1.Text = "Downloading image..." & path
Application.DoEvents()
Dim FTPResp As FtpWebResponse = ftpReq.GetResponse
Dim ftpRespStream As Stream = FTPResp.GetResponseStream
PictureBox1.Image = Image.FromStream(ftpRespStream)
FTPResp.Close()
ToolStripStatusLabel1.Text = _
"Downloading image...complete (" & path & ")"
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
To download an image file using FTP and then bind it to a PictureBox control:
- Create an instance of the FtpWebRequest class using the Create() method of the WebRequest class. The Create() method takes in a URI parameter (containing the path for the text file to be downloaded).
- Set the command to be sent to the FTP server using the Method property of the FtpWebRequest class; in this case the command is DownloadFile.
- Specify the login credential to the FTP server.
- Obtain the response from the FTP server using the GetResponse() method from the FtpWebRequest class.
- Retrieve the stream that contains response data sent from an FTP server using the GetResponseStream() method from the FtpWebResponse class.
- Use the FromStream() method from the Image class to convert the response from the FTP server (containing the image) into an image.