Windows DevCenter    
 Published on Windows DevCenter (http://www.windowsdevcenter.com/)
 See this if you're having trouble printing code examples


Building FTP Services Using .NET 2.0

by Wei-Meng Lee
12/12/2006

.NET 2.0 provides new managed classes for performing FTP accesses: FtpWebRequest and FtpWebResponse, which are derived from the WebRequest and WebResponse classes, respectively. Using these two new FTP classes, you can now incorporate FTP functionality into your applications easily. In this article, I will show you how to perform the most common FTP functions using these two new classes.

For this article, I will use the FTP service that is provided in Windows XP. My FTP site directory is mapped to C:\Inetpub\ftproot\. Figure 1 shows the initial content of my FTP directory.

Figure 1
Figure 1. The initial content of my FTP directory

All the coding in this article uses the two namespaces below:

Imports System.Net
Imports System.IO

Also, the following constant is defined:

    Const ftpURI As String = "ftp://127.0.0.1/"

In this article, I assume that the FTP server is configured for anonymous access and it is installed locally on your computer.

Downloading a Text File

To download a text file using FTP:

  1. 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).
  2. Set the command to be sent to the FTP server using the Method property of the FtpWebRequest class; in this case this command is DownloadFile.
  3. Specify the login credential to the FTP server.
  4. Obtain the response from the FTP server using the GetResponse() method from the FtpWebRequest class.
  5. Retrieve the stream that contains response data sent from an FTP server using the GetResponseStream() method from the FtpWebResponse class.

Note that you can use a StreamReader object to read the content of the text file:

Try
    Dim filename As String = ftpURI & "test.txt"
    Dim ftpReq As FtpWebRequest = WebRequest.Create(filename)

    ftpReq.Method = WebRequestMethods.Ftp.DownloadFile
    ftpReq.Credentials = New NetworkCredential("anonymous", "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)
    Console.WriteLine(reader.ReadToEnd)
Catch ex As Exception
    MsgBox(ex.ToString)
End Try

Downloading an Image File

If you want to download an image file from an FTP server and then directly bind it to, say, a PictureBox control, you can use the steps outlined above and then use the FromStream() method from the Image class to convert the response from the FTP server (containing the image) into an image:

Try
    Dim filename As String = ftpURI & "phidgetRFID.jpg"
    Dim ftpReq As FtpWebRequest = WebRequest.Create(filename)
    ftpReq.Method = WebRequestMethods.Ftp.DownloadFile
    ftpReq.Credentials = New NetworkCredential("anonymous", "password")

    Dim FTPResp As FtpWebResponse = ftpReq.GetResponse
    Dim ftpRespStream As Stream = FTPResp.GetResponseStream

    PictureBox1.Image = Image.FromStream(ftpRespStream)
Catch ex As Exception
    MsgBox(ex.ToString)
End Try

Downloading a Binary File

To download a binary file (in fact, any type of files, including text files) from an FTP server, the easiest way would be to use the WebClient class.

  1. First, create a new instance of the WebClient class.
  2. Specify the login credential to the FTP server.
  3. Download the file from the FTP server using the DownloadData() method from the WebClient class. Note that you need to specify the full pathname of the file to be downloaded from the FTP server.
  4. The DownloadData() method returns a byte array, which you can save directly onto a file using the WriteAllBytes() method from the My.Computer.FileSystem class.

Try
    Dim filename As String = ftpURI & "phidgetRFID.jpg"
    Dim client As New WebClient
    client.Credentials = New NetworkCredential("anonymous", "password")
    My.Computer.FileSystem.WriteAllBytes(".\phidgetRFID.jpg", _
       client.DownloadData(filename), True)
    MsgBox("File downloaded!")
Catch ex As Exception
    MsgBox(ex.ToString)
End Try

Note that you can also use the DownloadFile() method from the WebClient class to download and save a file directly to disk.

Uploading a Binary File

To upload a binary file (including text files) to an FTP server:

  1. First, create a new instance of the WebClient class.
  2. Specify the login credential to the FTP server.
  3. Upload the file to the FTP server using the UploadFile() method from the WebClient class. Note that you need to specify the full pathname of the file to be uploaded to the FTP server.

Try
    Dim filename As String = ftpURI & "PING.bmp"
    Dim client As New WebClient
    client.Credentials = New NetworkCredential("anonymous", "password")
    client.UploadFile(filename, "C:\PING.bmp")
    MsgBox("File uploaded!")
Catch ex As Exception
    MsgBox(ex.ToString)
End Try

Note that you can also use the UploadData() method from the WebClient class to upload an array of bytes.

Figure 2 shows the contents of my FTP directory after uploading the file PING.bmp.

Figure 2
Figure 2. The contents of my FTP directory after uploading the file

Uploading a Text File

To upload a text file to an FTP server:

  1. 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 file to be uploaded).
  2. Set the command to be sent to the FTP server using the Method property of the FtpWebRequest class; in this case this command is UploadFile.
  3. Specify the login credential to the FTP server.
  4. Use a StreamReader object to read the contents of the text file to be uploaded.
  5. Retrieve the stream used to upload data to an FTP server using the GetRequestStream() method of the FtpWebRequest class.
  6. Write the content of the text file to be uploaded into the stream.
  7. Obtain the response from the FTP server using the GetResponse() method from the FtpWebRequest class.
Try
    Dim filename As String = ftpURI & "test.txt"
    Dim ftpReq As FtpWebRequest = WebRequest.Create(filename)
    ftpReq.Method = WebRequestMethods.Ftp.UploadFile
    ftpReq.Credentials = New NetworkCredential("anonymous", "password")

    Dim stream As StreamReader = New StreamReader("C:\test.txt")
    Dim b() As Byte = _
       System.Text.Encoding.UTF8.GetBytes(stream.ReadToEnd())
    stream.Close()

    ftpReq.ContentLength = b.Length
    Dim s As Stream = ftpReq.GetRequestStream()
    s.Write(b, 0, b.Length)
    s.Close()

    Dim ftpResp As FtpWebResponse = ftpReq.GetResponse()
    MsgBox(ftpResp.StatusDescription)
Catch ex As Exception
    MsgBox(ex.ToString)
End Try

Removing a File

To remove a file from an FTP server:

  1. 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 file to be removed).
  2. Set the command to be sent to the FTP server using the Method property of the FtpWebRequest class; in this case this command is DeleteFile.
  3. Specify the login credential to the FTP server.
  4. Obtain the response from the FTP server using the GetResponse() method from the FtpWebRequest class.
Try
    Dim filename As String = ftpURI & "PING.bmp"
    Dim ftpReq As FtpWebRequest = WebRequest.Create(filename)
    ftpReq.Method = WebRequestMethods.Ftp.DeleteFile
    ftpReq.Credentials = New NetworkCredential("anonymous", "password")

    Dim ftpResp As FtpWebResponse = ftpReq.GetResponse
    MsgBox(ftpResp.StatusDescription)
Catch ex As Exception
    MsgBox(ex.ToString)
End Try

Making a New Directory

To create a new directory on an FTP server:

  1. 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 of the new directory to create).
  2. Set the command to be sent to the FTP server using the Method property of the FtpWebRequest class; in this case this command is MakeDirectory.
  3. Specify the login credential to the FTP server.
  4. Obtain the response from the FTP server using the GetResponse() method from the FtpWebRequest class.
Try
    Dim filename As String = ftpURI & "User1"
    Dim ftpReq As FtpWebRequest = WebRequest.Create(filename)
    ftpReq.Method = WebRequestMethods.Ftp.MakeDirectory
    ftpReq.Credentials = New NetworkCredential("anonymous", "password")

    Dim ftpResp As FtpWebResponse = ftpReq.GetResponse
    MsgBox(ftpResp.StatusDescription)
Catch ex As Exception
    MsgBox(ex.ToString)
End Try

Figure 3 shows the contents of my FTP directory after creating the new directory User1.

Figure 3
Figure 3. The contents of my FTP directory after making a new directory

Viewing Directory Listing

To view the directory listing of an FTP account:

  1. 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).
  2. Set the command to be sent to the FTP server using the Method property of the FtpWebRequest class; in this case this command is ListDirectoryDetails.
  3. Specify the login credential to the FTP server.
  4. Obtain the response from the FTP server using the GetResponse() method from the FtpWebRequest class.
  5. Retrieve the stream that contains response data sent from an FTP server using the GetResponseStream() method from the FtpWebResponse class.

Note that you can use a StreamReader object to read the directory listing.

Try
    Dim ftpReq As FtpWebRequest = WebRequest.Create(ftpURI)
    ftpReq.Method = WebRequestMethods.Ftp.ListDirectoryDetails
    ftpReq.Credentials = New NetworkCredential("anonymous", "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)
    Console.WriteLine(reader.ReadToEnd)
Catch ex As Exception
    MsgBox(ex.ToString)
End Try

Depending on how the FTP server is configured, you will see something like this:

(MS-DOS Directory Listing Style)
10-19-06  11:14AM                19387 phidgetRFID.jpg
12-08-06  02:01PM               242490 PING.bmp
12-08-06  10:32AM                    5 test.txt
12-08-06  02:26PM       <DIR>          User1

or:

(UNIX Directory Listing Style)
-r-xr-xr-x   1 owner    group           19387 Oct 19 11:14 phidgetRFID.jpg
-rwxrwxrwx   1 owner    group          242490 Dec  8 14:01 PING.bmp
-r-xr-xr-x   1 owner    group               5 Dec  8 10:32 test.txt
drwxrwxrwx   1 owner    group               0 Dec  8 14:26 User1

Note that you need to manually parse the directory listing to differentiate the directories from the files. The FTP classes in .NET 2.0 does not provision for this.

Removing a Directory

To remove a directory on an FTP server:

  1. 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 of the new directory to remove).
  2. Set the command to be sent to the FTP server using the Method property of the FtpWebRequest class; in this case this command is RemoveDirectory.
  3. Specify the login credential to the FTP server.
  4. Obtain the response from the FTP server using the GetResponse() method from the FtpWebRequest class.
Try
    Dim filename As String = ftpURI & "User1"
    Dim ftpReq As FtpWebRequest = WebRequest.Create(filename)
    ftpReq.Method = WebRequestMethods.Ftp.RemoveDirectory
    ftpReq.Credentials = New NetworkCredential("anonymous", "password")

    Dim ftpResp As FtpWebResponse = ftpReq.GetResponse
    MsgBox(ftpResp.StatusDescription)
Catch ex As Exception
    MsgBox(ex.ToString)
End Try

Summary

While the new FTP classes in .NET 2.0 make transferring files between clients and FTP servers easy, they does have their shortcomings. For example, you need to maintain your own state, as each request requires a full valid path. This is evident if you try to implement a full-blown FTP client that allows users to navigate directories. In this case, you need to know exactly which directory the user is in before you can get a listing of files in that particular directory (since the FTP classes do not remember the current directory). However, if all you need is access to an FTP server for simple file transfer, the new managed classes in .NET 2.0 are worth a look.

Wei-Meng Lee (Microsoft MVP) http://weimenglee.blogspot.com is a technologist and founder of Developer Learning Solutions http://www.developerlearningsolutions.com, a technology company specializing in hands-on training on the latest Microsoft technologies.


Return to the Windows DevCenter.

Copyright © 2009 O'Reilly Media, Inc.