Section 6.4. Upload and Download Files with FTP


6.4. Upload and Download Files with FTP

Earlier versions of .NET didn't include any tools for FTP (File Transfer Protocol), a common protocol used to transfer files to and from a web server. As a result, you either had to purchase a third-party component or write your own (which was easy in principle but difficult to get right in practice).


Note: Need to upload files to an FTP site or download existing content? New support is available in VB 2005.

In .NET 2.0, a new FtpWebRequest class neatly fills the gap. However, the FtpWebRequest class has its own complexities, so Microsoft programmers simplified life for VB developers even further by extending the My.Computer.Network object to provide two quick access methods for completing basic FTP operations. These are UploadFile(), which sends a file to a remote server, and DownloadFile( ), which retrieves a file and stores it locally.

6.4.1. How do I do that?

Whether you use the FtpWebRequest class or the My.Computer.Network object, all FTP interaction in .NET is stateless. That means that you connect to the FTP site, perform a single operation (like transferring a file or retrieving a directory listing), and then disconnect. If you need to perform another operation, you need to reconnect. Fortunately, this process of connecting and logging in is handled automatically by the .NET Framework.

The easiest way to use FTP in a VB application is to do so through the My.Computer.Network object. If you use its FTP methods, you never need to worry about the tedious details of opening, closing, and reading streams. To download a file, the bare minimum information you need is the URL that points to the FTP site and the path that points to the local file. Here's an example:

My.Computer.Network.DownloadFile( _   "ftp://ftp.funet.fi/pub/gnu/prep/gtk.README", "c:\readme.txt")

This command retrieves the file that is on the FTP site ftp.funet.fi in the path /pub/gnu/prep/gtk.README and copies it to the local file c:\readme.txt.

Uploading uses similar parameters, but in reverse:

My.Computer.Network.UploadFile("c:\newfile.txt", _   "ftp://ftp.funet.fi/pub/newfile.txt")

This command copies the local file newfile.txt from the directory c:\ to the FTP site ftp.funet.fi, in the remote directory /pub.

Both DownloadFile( ) and UploadFile( ) support several overloads that take additional parameters, including credentials (the username and password information you might need to log on to a server) and a timeout parameter to set the maximum amount of time you'll wait for a response before giving up (the default is 1,000 milliseconds).

Unfortunately, the DownloadFile( ) and UploadFile( ) methods haven't been too robust in beta builds of Visual Basic 2005, and the methods may fail to work. An option that works better is the more sophisticated FtpWebRequest class. Not only does it perform more reliably, but it also fills a few glaring gaps in the FTP support provided by the My.Network.Computer. Because FtpWebRequest allows you to execute any FTP command, you can use it to retrieve directory listings, get file information, and more.


Note: Internet Explorer has its own built-in FTP browser. Just type a URL that points to an FTP site (like ftp://ftp.microsoft.com) into the IE address bar to browse what's there. You can use this tool to verify that your code is working correctly.

To use the FtpWebRequest class, you need to follow several steps. First, pass the URL that points to the FTP site to the shared WebRequest.Create( ) method:

Dim Request As FtpWebRequest  Request = CType(WebRequest.Create("ftp://ftp.microsoft.com/MISC"), _   FtpWebRequest)

The WebRequest.Create() method examines the URL and returns the appropriate type of WebRequest object. Because FTP URLs always start with the scheme ftp://, the Create( ) method will return a new FtpWebRequest object.

Once you have the FtpWebRequest, you need to choose what FTP operation you want to perform by setting the FtpWebRequest.Method property with the text of the FTP command. Here's an example for retrieving directory information with the LIST command:

Request.Method = "LIST"

Once you've chosen the FTP operation you want to perform, the last step is to execute the command and read the response. The tricky part is the fact that the response is returned to you as a stream of text. It's up to you to move through this block of text line by line with a StreamReader and parse the information.

For example, the following code reads through a returned directory listing and displays each line in a Console window:

Dim Response As FtpWebResponse = CType(Request.GetResponse( ), FtpWebResponse) Dim ResponseStream As Stream = Response.GetResponseStream( ) Dim Reader As New StreamReader(ResponseStream, System.Text.Encoding.UTF8)      Dim Line As String Do     Line = Reader.ReadLine( )     Console.WriteLine(Line) Loop Until Line = ""

The output looks like this:

dr-xr-xr-x   1 owner    group               0 Jul  3  2002 beckyk -r-xr-xr-x   1 owner    group           15749 Apr  8  1994 CBCP.TXT dr-xr-xr-x   1 owner    group               0 Jul  3  2002 csformat dr-xr-xr-x   1 owner    group               0 Aug  1  2002 DAILYKB -r-xr-xr-x   1 owner    group             710 Apr 12  1993 DISCLAIM.TXT dr-xr-xr-x   1 owner    group               0 Jul  3  2002 FDC dr-xr-xr-x   1 owner    group               0 Jul  3  2002 friKB dr-xr-xr-x   1 owner    group               0 Jul  3  2002 FULLKB dr-xr-xr-x   1 owner    group               0 Jul  3  2002 Homenet -r-xr-xr-x   1 owner    group              97 Sep 28  1993 INDEX.TXT ...

Clearly, if you want to manipulate individual pieces of information (like the file size) or distinguish files from directories, you'll need to do extra work to parse the text returned by the StreamReader.

Finally, when you're finished with the FTP request and response, you need to close the streams:

Reader.Close( ) Response.Close( )

To put it all in context, it helps to consider a simple FTP browsing application. Figure 6-1 shows a sample application that's included with the downloadable samples for this chapter.

Figure 6-1. A simple FTP Browser application


This Windows application includes the following controls:

  • A TextBox where you can enter a URL that points to a file or directory in an FTP site.

  • A Button named Query Directory that retrieves the folders and files at a given URL. This task requires the FtpWebRequest class.

  • A Button named Download File that downloads the file at a given URL. This task uses the My.Computer.Network.DownloadFile( ) method.

  • A FolderBrowserDialog that allows you to choose a folder where the downloaded file will be saved.

  • A ListView that shows the directory and file listing for the URL. This list is refreshed every time you click the Query Directory button. In addition, every time you click to select an item in the ListView, that information is automatically added to the URL in the text box. This allows you to quickly browse through an FTP site, drilling down several layers into the directory structure and selecting the file that interests you.

Example 6-4 shows code for the FTP browser form

Example 6-4. The FTP browser form
Public Class FtpForm     Inherits System.Windows.Forms.Form     ' Stores the path currently shown in the ListView.     Private CurrentPath As String     Private Sub cmdQuery_Click(ByVal sender As System.Object, _       ByVal e As System.EventArgs) Handles cmdQuery.Click         ' Check the URI is valid.         Dim RequestUri As Uri = ValidateUri(txtFtpSite.Text)         If RequestUri Is Nothing Then Return         ' Clear the ListView.         listDir.Items.Clear( )         ' Create a new FTP request using the URI.         Dim Request As FtpWebRequest         Request = CType(WebRequest.Create(RequestUri), FtpWebRequest)         ' Use this request for getting full directory details.         Request.Method = "LIST"          Request.UsePassive = False         Dim Response As FtpWebResponse         Dim ResponseStream As Stream         Dim Reader As StreamReader         Try             ' Execute the command and get the response.             Response = CType(Request.GetResponse( ), FtpWebResponse)             Debug.WriteLine("Status: " & Response.StatusDescription)             ' Read the response one line at a time.             ResponseStream = Response.GetResponseStream( )             Reader = New StreamReader(ResponseStream, System.Text.Encoding.UTF8)             Dim Line As String             Do                 Line = Reader.ReadLine( )                 If Line <> "" Then                     Debug.WriteLine(Line)                     ' Extract just the file or directory name from the line.                     Dim ListItem As New ListViewItem(Line.Substring(59).Trim( ))                     If Line.Substring(0, 1) = "d" Then                         ListItem.ImageKey = "Folder"                     Else                         ListItem.ImageKey = "File"                     End If                     listDir.Items.Add(ListItem)                 End If             Loop Until Line = ""             ' Operation completed successfully. Store the current FTP path.             CurrentPath = RequestUri.ToString( )         Catch Ex As Exception             MessageBox.Show(Ex.Message)         Finally             ' Clean up.             Reader.Close( )             Response.Close( )         End Try     End Sub     Private Sub cmdDownload_Click(ByVal sender As System.Object, _       ByVal e As System.EventArgs) Handles cmdDownload.Click         ' Check the URI is valid.         Dim RequestUri As Uri = ValidateUri(txtFtpSite.Text)         If RequestUri Is Nothing Then Return         ' Prompt the user to choose a destination folder.         ' Default the file name to the same file name used on the FTP server.         dlgSave.FileName = Path.GetFileName(txtFtpSite.Text)         If dlgSave.ShowDialog( ) <> Windows.Forms.DialogResult.OK Then             Return         End If         ' Create a new FTP request using the URI.         Dim Request As FtpWebRequest         Request = CType(WebRequest.Create(RequestUri), FtpWebRequest)         ' Use this request for downloading the file.         Request.UsePassive = False         Request.Method = "RETR"           Dim Response As FtpWebResponse         Dim ResponseStream, TargetStream As Stream         Dim Reader As StreamReader         Dim Writer As StreamWriter         Try             ' Execute the command and get the response.             Response = CType(Request.GetResponse( ), FtpWebResponse)             Debug.WriteLine("Status: " & Response.StatusDescription)             Debug.WriteLine("File Size: " & Response.ContentLength)             ' Create the destination file.             TargetStream = New FileStream(dlgSave.FileName, FileMode.Create)             Writer = New StreamWriter(TargetStream)             ' Write the response to the file.             ResponseStream = Response.GetResponseStream( )             Reader = New StreamReader(ResponseStream, System.Text.Encoding.UTF8)             Writer.Write(Reader.ReadToEnd( ))         Catch Err As Exception             MessageBox.Show(Err.Message)         Finally             ' Clean up.             Reader.Close( )             Response.Close( )             Writer.Close( )         End Try     End If     End Sub     Private Function ValidateUri(ByVal uriText As String) As Uri         Dim RequestUri As Uri         Try             ' Check that the string is interpretable as a URI.             RequestUri = New Uri(uriText)             ' Check that the URI starts with "ftp://"             If RequestUri.Scheme <> Uri.UriSchemeFtp Then                 RequestUri = Nothing             End If         Catch             RequestUri = Nothing         End Try         If RequestUri Is Nothing Then             MessageBox.Show("Invalid Uri.")         Else         End If         Return RequestUri     End Function     Private Sub listDir_SelectedIndexChanged(ByVal sender As System.Object, _       ByVal e As System.EventArgs) Handles listDir.SelectedIndexChanged         ' When a new item is selected in the list, add this          ' to the URI in the text box.         If listDir.SelectedItems.Count <> 0 Then             CurrentPath = CurrentPath.TrimEnd("/")             txtFtpSite.Text = CurrentPath & "/" & listDir.SelectedItems(0).Text         End If     End Sub End Class

The most complex code found in this example occurs in the event handler for the cmdQuery button, which retrieves a directory listing, parses out the important information, and updates the ListView.

6.4.2. Where can I learn more?

In previous builds, the MSDN help included much more information on FTP access and different FTP operations under the index entry "FtpMethods," complete with useful demonstrations of the different methods. This entry has disappeared in recent builds (along with the FtpMethods class), but check for it to return. In the meantime, you can read up on the FTP protocol and supported commands at www.vbip.com/winsock/winsock_ftp_ref_01.asp.



Visual Basic 2005(c) A Developer's Notebook
Visual Basic 2005: A Developers Notebook
ISBN: 0596007264
EAN: 2147483647
Year: 2006
Pages: 123

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net