Now that we've reviewed FTP methods in Visual Basic, let's put them to work. Our goal in our example program, FTPer, is to download the directory of ftp.microsoft.com, indicate which text files are available, and let the user download the selected one:
This example is not very fancy, so the Internet Transfer control OpenURL() method will work best here. Using this method, you can fetch files with the HTTP and FTP protocols. That's all it does—if you want to use commands such as DIR or PUT, you must use the Execute method.
Now that we've added an Internet Transfer control to our FTPer project, we can put it to work. When the program starts, we'll have it automatically connect to ftp.microsoft.com and display a directory listing of the text files there (the files with the extension .txt). We will use the Form_Load() event handler, which is called when the main form is first displayed; currently it looks like this (where the program positions the form on the screen and sizes it):
Private Sub Form_Load()
Me.Left = GetSetting(App.Title, "Settings", "MainLeft", 1000)
Me.Top = GetSetting(App.Title, "Settings", "MainTop", 1000)
Me.Width = GetSetting(App.Title, "Settings", "MainWidth", 6500)
Me.Height = GetSetting(App.Title, "Settings", "MainHeight", 6500)
End Sub
Next, we get the directory of the Microsoft server ftp.microsoft.com. We use the OpenURL() method, loading the directory information into a string named DirectoryText:
Private Sub Form_Load()
—> Dim DirectoryText
Me.Left = GetSetting(App.Title, "Settings", "MainLeft", 1000)
Me.Top = GetSetting(App.Title, "Settings", "MainTop", 1000)
Me.Width = GetSetting(App.Title, "Settings", "MainWidth", 6500)
Me.Height = GetSetting(App.Title, "Settings", "MainHeight", 6500)
—> DirectoryText = Inet1.OpenURL("ftp://ftp.microsoft.com")
.
.
.
Because we have not specified a file to download, we will get a listing of ftp.microsoft.com's directory. In general, the OpenURL() method has two arguments: the URL you want to get and a data type setting, which can hold the values icString (= 0, the default) to retrieve the data as a string, or icByteArray (= 1) to retrieve the data as a byte array. Although we skipped the second parameter, we could also have written that line this way:
DirectoryText = Inet1.OpenURL("ftp://ftp.microsoft.com", icString)
When the program executes this line, it connects to the Internet (assuming that the user has a connection set up for the Internet) if the computer is not already connected and logs in to ftp.microsoft.com. Then it gets the directory of ftp.microsoft.com and places it into the string DirectoryString. With the addition of the Inet1 control to our program and the use of the OpenURL() method, we've connected to the Internet using the FTP protocol.
We can get the length of the directory data by checking the length of the string DirectoryString:
Private Sub Form_Load()
Dim DirectoryText
Me.Left = GetSetting(App.Title, "Settings", "MainLeft", 1000)
Me.Top = GetSetting(App.Title, "Settings", "MainTop", 1000)
Me.Width = GetSetting(App.Title, "Settings", "MainWidth", 6500)
Me.Height = GetSetting(App.Title, "Settings", "MainHeight", 6500)
DirectoryText = Inet1.OpenURL("ftp://ftp.microsoft.com")
—> DirectoryTextLength = Len(DirectoryText)
.
.
.
End Sub
Here's the actual data we would receive for the directory of ftp.microsoft.com; note that it is set up in HTML to make it easy for Web browsers:
<BODY>
<H2>FTP root at ftp.microsoft.com</H2>
<HR>
<H4><PRE>
This is FTP.MICROSOFT.COM. Please see the
dirmap.txt file for more information.
</PRE></H4>
<HR>
<PRE>
09/20/96 07:34PM Directory <A HREF="/bussys/"><B>bussys</B></A>
09/23/96 08:46PM Directory <A HREF="/deskapps/"><B>deskapps</B></A>
08/16/96 05:33PM Directory <A HREF="/developr/"><B>developr</B></A>
09/11/96 01:01AM 8,012 <A HREF="/dirmap.htm">dirmap.htm</A>
09/11/96 12:57AM 4,368 <A HREF="/dirmap.txt">dirmap.txt</A>
08/25/94 12:00AM 712 <A HREF="/disclaimer.txt">disclaimer.txt</A>
11/19/96 01:23AM Directory <A HREF="/KBHelp/"><B>KBHelp</B></A>
12/03/96 11:10AM 8,168,053 <A HREF="/ls-lR.txt">ls-lR.txt</A>
12/03/96 11:10AM 1,065,823 <A HREF="/ls-lR.Z">ls-lR.Z</A>
12/03/96 11:10AM 879,116 <A HREF="/LS-LR.ZIP">LS-LR.ZIP</A>
10/20/95 12:00AM Directory <A HREF="/MSCorp/"><B>MSCorp</B></A>
10/27/96 12:24AM Directory <A HREF="/msdownload/"><B>msdownload</B></A>
10/11/95 12:00AM Directory <A HREF="/peropsys/"><B>peropsys</B></A>
11/30/95 12:00AM Directory <A HREF="/Products/"><B>Products</B></A>
10/28/96 11:47PM Directory <A HREF="/Services/"><B>Services</B></A>
05/30/96 01:39AM Directory <A HREF="/Softlib/"><B>Softlib</B></A>
04/08/96 02:21PM Directory <A HREF="/solutions/"><B>solutions</B></A>
</PRE>
<HR>
</BODY>
</HTML>
We want to place the names of the text files into the listbox List1, so we will write our program to search through the listing for .txt files; we do that by searching for ".txt," which locates the end of the file name strings that we want. We will place each file name into its own string, so we call the location of the substring ".txt" StringEnd (the end of the file name string):
Private Sub Form_Load()
Dim DirectoryText
Me.Left = GetSetting(App.Title, "Settings", "MainLeft", 1000)
Me.Top = GetSetting(App.Title, "Settings", "MainTop", 1000)
Me.Width = GetSetting(App.Title, "Settings", "MainWidth", 6500)
Me.Height = GetSetting(App.Title, "Settings", "MainHeight", 6500)
DirectoryText = Inet1.OpenURL("ftp://ftp.microsoft.com")
DirectoryTextLength = Len(DirectoryText)
—> StringEnd = InStr(DirectoryText, ".txt""")
.
.
.
End Sub
As long as the variable StringEnd is not 0, we have found a match. We should set up a loop, because there will be more than one text file to find:
Private Sub Form_Load()
Dim DirectoryText
Me.Left = GetSetting(App.Title, "Settings", "MainLeft", 1000)
Me.Top = GetSetting(App.Title, "Settings", "MainTop", 1000)
Me.Width = GetSetting(App.Title, "Settings", "MainWidth", 6500)
Me.Height = GetSetting(App.Title, "Settings", "MainHeight", 6500)
DirectoryText = Inet1.OpenURL("ftp://ftp.microsoft.com")
DirectoryTextLength = Len(DirectoryText)
StringEnd = InStr(DirectoryText, ".txt""")
—> While (StringEnd <> 0)
.
.
.
—> Wend
End Sub
Because the directory of ftp.microsoft.com is set up as a Web page (which is quite common), each file name is enclosed in quotation marks:
09/11/96 12:57AM 4,368 <A HREF="/dirmap.txt">dirmap.txt</A>
Now that we've found the ".txt" part of the file name, we can work back to the quotation mark to get the whole file name and the length of the file name (which we place in the variable StringLength):
Private Sub Form_Load()
Dim DirectoryText
Me.Left = GetSetting(App.Title, "Settings", "MainLeft", 1000)
Me.Top = GetSetting(App.Title, "Settings", "MainTop", 1000)
Me.Width = GetSetting(App.Title, "Settings", "MainWidth", 6500)
Me.Height = GetSetting(App.Title, "Settings", "MainHeight", 6500)
DirectoryText = Inet1.OpenURL("ftp://ftp.microsoft.com")
DirectoryTextLength = Len(DirectoryText)
StringEnd = InStr(DirectoryText, ".txt""")
While (StringEnd <> 0)
—> StringLength = 0
—> While (InStr(StringEnd - StringLength, Left(DirectoryText,
—> StringEnd),
—> """") = 0)
—> StringLength = StringLength + 1
—> Wend
—> StringLength = StringLength - 1
.
.
.
Wend
End Sub
At this point, we've found a file name in the FTP directory. We know how long it is, so we add it to our listbox List1 this way:
Private Sub Form_Load()
Dim DirectoryText
Me.Left = GetSetting(App.Title, "Settings", "MainLeft", 1000)
Me.Top = GetSetting(App.Title, "Settings", "MainTop", 1000)
Me.Width = GetSetting(App.Title, "Settings", "MainWidth", 6500)
Me.Height = GetSetting(App.Title, "Settings", "MainHeight", 6500)
DirectoryText = Inet1.OpenURL("ftp://ftp.microsoft.com")
DirectoryTextLength = Len(DirectoryText)
StringEnd = InStr(DirectoryText, ".txt""")
While (StringEnd <> 0)
StringLength = 0
While (InStr(StringEnd - StringLength, Left(DirectoryText,
StringEnd),
"""") = 0)
StringLength = StringLength + 1
Wend
StringLength = StringLength - 1
—> List1.AddItem Mid(DirectoryText, StringEnd - StringLength + 1,
StringLength - 1) + ".txt"
.
.
.
Wend
End Sub
Next, we truncate the directory listing string (we won't need it for anything else, so we remove the parts we've already searched) to remove the already-found file name. Then we loop again to find the next occurrence of ".txt":
Private Sub Form_Load()
Dim DirectoryText
Me.Left = GetSetting(App.Title, "Settings", "MainLeft", 1000)
Me.Top = GetSetting(App.Title, "Settings", "MainTop", 1000)
Me.Width = GetSetting(App.Title, "Settings", "MainWidth", 6500)
Me.Height = GetSetting(App.Title, "Settings", "MainHeight", 6500)
DirectoryText = Inet1.OpenURL("ftp://ftp.microsoft.com")
DirectoryTextLength = Len(DirectoryText)
StringEnd = InStr(DirectoryText, ".txt""")
While (StringEnd <> 0)
StringLength = 0
While (InStr(StringEnd - StringLength, Left(DirectoryText,
StringEnd),
"""") = 0)
StringLength = StringLength + 1
Wend
StringLength = StringLength - 1
List1.AddItem Mid(DirectoryText, StringEnd - StringLength + 1,
StringLength - 1) + ".txt"
—> DirectoryText = Right(DirectoryText, DirectoryTextLength -
—> StringEnd)
—> DirectoryTextLength = DirectoryTextLength - StringEnd
—> StringEnd = InStr(DirectoryText, ".txt""")
Wend
End Sub
At this point, our listbox displays the names of the .txt files:
All that remains is to read the files from the FTP server when the user double-clicks its name in the listbox. We use List1_Click(), creating the full name of the file to fetch by adding "ftp://ftp.microsoft.com/" to the name of the file we are supposed to get in List1.Text:
Private Sub List1_Click()
RichTextBox1.Text = Inet1.OpenURL("ftp://ftp.microsoft.com/" + List1.Text)
End Sub
That's it—the program is now functional. Run it to see the listing of the .txt files in the FTP server ftp.microsoft.com, as shown in Figure 3.1. Now click a file, such as disclaimer.txt, and it will be downloaded and appear in the rich text box. Our FTP program is a success.
Figure 3.1 Retrieving files from Microsoft via FTP.
That's how to download text. Although we can use the Execute() method, it's usually easier to use OpenURL() if we just want to download a file. We can download binary data, too. Let's look into that now.