FTP Tutorial
Applies to: Rebex Total Pack, Rebex File Transfer Pack, Rebex FTP
Table of content
Namespaces and assemblies
To use the features of Rebex for .NET described here, you have to reference
the Rebex.Ftp.dll, Rebex.Common.dll and Rebex.Networking.dll
assemblies in your project.
They contains the Ftp
and other classes in Rebex.Net namespace.
In your source files, import the following namespace:
using Rebex.Net;
Imports Rebex.Net
FTP basics - connecting, logging in and disconnecting
Typical FTP session goes like this:
- Connect to the FTP server
- Login - authenticate with user name and password
- Browse directories and transfer files
- Disconnect
There are many FTP servers that allow anonymous access. You have to call the Login
method as well for these: just use "anonymous" for username and your e-mail address for password,
or try the "guest" password if you don't want to disclose your e-mail - most FTP servers allow this
as well. Or pass null
(Nothing
in Visual Basic) for username and password
to achieve the same thing.
And now let's look at some sample code.
// create client and connect Ftp client = new Ftp(); client.Connect("ftp.example.org"); // authenticate client.Login("username", "password"); // browse directories, transfer files // ... // disconnect client.Disconnect();
' create client and connect Dim client As New Ftp client.Connect("ftp.example.org") ' authenticate client.Login("username", "password") ' browse directories, transfer files ' ... ' disconnect client.Disconnect()
During a single FTP session, only one operation such as file transfer can be active at the same time. However, if you really need to transfer more files simultaneously, or browse directories while a file transfer is in progress, you might initiate multiple FTP sessions to the same servers - most servers are configured to allow this.
Working with directories
Working with directories (folders) on the FTP server is simple. The remote filesystem is organized
in the same way as in Un*x. If you are used to Windows, watch out for the two differencies -
a slash (/
) is used instead of a backslash, and there is only a single root at "/",
no drive letters. A typical path to a file might look like "/pub/incoming/test.zip", for example.
// create client, connect and log in Ftp client = new Ftp(); client.Connect("ftp.example.org"); client.Login("username", "password"); // determine current directory Console.WriteLine("Current directory: {0}", client.GetCurrentDirectory()); // create the 'top' directory at the root level client.CreateDirectory("/top"); // create the 'first' directory in the '/top' directory client.CreateDirectory("/top/first"); // change the current directory to '/top' client.ChangeDirectory("/top"); // create the 'second' directory in the current folder // (note: we used a relative path this time) client.CreateDirectory("second"); // remove the 'first' directory we created earlier client.RemoveDirectory("first"); // change the current directory to a parent, // (note: '..' has the same meaning as in Windows and Un*x client.ChangeDirectory("..");
' create client, connect and log in Dim client As New Ftp client.Connect("ftp.example.org") client.Login("username", "password") ' determine current directory Console.WriteLine("Current directory: {0}", client.GetCurrentDirectory()) ' create the 'top' directory at the root level client.CreateDirectory("/top") ' create the 'first' directory in the '/top' directory client.CreateDirectory("/top/first") ' change the current directory to '/top' client.ChangeDirectory("/top") ' create the 'second' directory in the current folder ' (note: we used a relative path this time) client.CreateDirectory("second") ' remove the 'first' directory we created earlier client.RemoveDirectory("first") ' change the current directory to a parent, ' (note: '..' has the same meaning as in Windows and Un*x client.ChangeDirectory("..")
Uploading and downloading files
File transfers are the essential part of the FTP protocol and can be achieved using
the GetFile
and PutFile
methods. They accept the path to the local
file and the path to the remote file (both paths must include the filename) and return the
number of bytes transferred (as long integer).
Other variants are also available that accept local and remote offsets, or streams instead
of local files - it is easy to use .NET's MemoryStream
to upload and download data
from and to memory instead of disk.
// create client, connect and log in Ftp client = new Ftp(); client.Connect("ftp.example.org"); client.Login("username", "password"); // upload the 'test.zip' file to the current directory at the server client.PutFile(@"c:\data\test.zip", "test.zip"); // upload the 'index.html' file to the specified directory at the server client.PutFile(@"c:\data\index.html", "/wwwroot/index.html"); // download the 'test.zip' file from the current directory at the server client.GetFile("test.zip", @"c:\data\test.zip"); // download the 'index.html' file from the specified directory at the server client.GetFile("/wwwroot/index.html", @"c:\data\index.html"); // upload a text using a MemoryStream string message = "Hello from Rebex FTP for .NET!"; byte[] data = System.Text.Encoding.Default.GetBytes(message); System.IO.MemoryStream ms = new System.IO.MemoryStream(data); client.PutFile(ms, "message.txt");
' create client, connect and log in Dim client As New Ftp client.Connect("ftp.example.org") client.Login("username", "password") ' upload the 'test.zip' file to the current directory at the server client.PutFile("c:\data\test.zip", "test.zip") ' upload the 'index.html' file to the specified directory at the server client.PutFile("c:\data\index.html", "/wwwroot/index.html") ' download the 'test.zip' file from the current directory at the server client.GetFile("test.zip", "c:\data\test.zip") ' download the 'index.html' file from the specified directory at the server client.GetFile("/wwwroot/index.html", "c:\data\index.html") ' upload a text using a MemoryStream Dim message As String = "Hello from Rebex FTP for .NET!" Dim data As Byte() = System.Text.Encoding.Default.GetBytes(message) Dim ms As New System.IO.MemoryStream(data) client.PutFile(ms, "message.txt")
List of files and directories
The format of the list of the contents of a directory is not defined by the FTP RFC, and varies substantially from server to server. But with Rebex FTP, retrieving and accessing the list of files in a directory is extremely easy - the GetList method does all the hard work and parses all common list formats automatically!
The following code snippet displays the list of files in the remote directory to a console:
// create client, connect and log in Ftp client = new Ftp(); client.Connect("ftp.example.org"); client.Login("username", "password"); // select the desired directory client.ChangeDirectory("path"); // retrieve and display the list of files and directories FtpItemCollection list = client.GetList(); foreach (FtpItem item in list) { Console.Write(item.LastWriteTime.GetValueOrDefault().ToString("u")); Console.Write(item.Length.ToString().PadLeft(10, ' ')); Console.Write(" {0}", item.Name); Console.WriteLine(); }
' create client, connect and log in Dim client As New Ftp client.Connect("ftp.example.org") client.Login("username", "password") ' select the desired directory client.ChangeDirectory("path") ' retrieve and display the list of files and directories Dim list As FtpItemCollection = client.GetList() Dim item As FtpItem For Each item In list Console.Write(item.LastWriteTime.GetValueOrDefault().ToString("u")) Console.Write(item.Length.ToString().PadLeft(10, " "c)) Console.Write(" {0}", item.Name) Console.WriteLine() Next item
Transferring multiple files and directories
Upload or download of multiple files is a very common task.
There are Download
and Upload
methods that can be used to
transfer multiple files easily - just provide the source path (which can be a directory or
contain wildcards), destination path and traversal mode.
// create client, connect and log in Ftp client = new Ftp(); client.Connect("ftp.example.org"); client.Login("username", "password"); // upload the content of 'c:\data' directory and all subdirectories // to the '/wwwroot' directory at the server client.Upload(@"c:\data\*", "/wwwroot", TraversalMode.Recursive); // upload all '.html' files in 'c:\data' directory // to the '/wwwroot' directory at the server client.Upload(@"c:\data\*.html", "/wwwroot", TraversalMode.MatchFilesShallow, TransferMethod.Copy, ActionOnExistingFiles.OverwriteAll); // download the content of '/wwwroot' directory and all subdirectories // at the server to the 'c:\data' directory client.Download("/wwwroot/*", @"c:\data", TraversalMode.Recursive); // download all '.html' files in '/wwwroot' directory at the server // to the 'c:\data' directory client.Download("/wwwroot/*.html", @"c:\data", TraversalMode.MatchFilesShallow, TransferMethod.Copy, ActionOnExistingFiles.OverwriteAll);
' create client, connect and log in Dim client As New Ftp client.Connect("ftp.example.org") client.Login("username", "password") ' upload the content of 'c:\data' directory and all subdirectories ' to the '/wwwroot' directory at the server client.Upload("c:\data\*", "/wwwroot", TraversalMode.Recursive) ' upload all '.html' files in 'c:\data' directory ' to the '/wwwroot' directory at the server client.Upload("c:\data\*.html", "/wwwroot", TraversalMode.MatchFilesShallow, _ TransferMethod.Copy, ActionOnExistingFiles.OverwriteAll) ' download the content of '/wwwroot' directory and all subdirectories ' at the server to the 'c:\data' directory client.Download("/wwwroot/*", "c:\data", TraversalMode.Recursive) ' download all '.html' files in '/wwwroot' directory at the server ' to the 'c:\data' directory client.Download("/wwwroot/*.html", "c:\data", TraversalMode.MatchFilesShallow, _ TransferMethod.Copy, ActionOnExistingFiles.OverwriteAll)
For transferring files from the current directory use asterisk (*). For example
client.Download("*", localPath)
.
When transferring lots of files, things can occasionally go wrong due to unforeseen problems -
to be informed about such errors, use ProblemDetected
event that also makes
it possible to select the desired next action. To stay informed about what is currently going on,
use the TransferProgressChanged
event.
// add event handler that gets called when a problem is detected during the multi file // transfer (this is optional) - the event handler can select the desired next action client.ProblemDetected += new EventHandler<FtpProblemDetectedEventArgs>(client_ProblemDetected); // add event handler that gets called when significant action occurs during // traversing hierarchy structure (this is optional) client.Traversing += new EventHandler<FtpTraversingEventArgs>(client_Traversing); // add event handler that gets called when a significant action occurs during // the batch transfer (this is optional) client.TransferProgressChanged += new EventHandler<FtpTransferProgressChangedEventArgs>(client_TransferProgressChanged); // upload or download files client.Upload(localPath, remotePath, TraversalMode.Recursive); // of course, the client_ProblemDetected, client_Traversing and client_TransferProgressChanged methods // have to be implemented - check out the FtpBatchTransfer sample for more information
' add event handler that gets called when a problem is detected during the multi file ' transfer (this is optional) - the event handler can select the desired next action AddHandler client.ProblemDetected, AddressOf client_ProblemDetected ' add event handler that gets called when significant action occurs during ' traversing hierarchy structure (this is optional) AddHandler client.Traversing, AddressOf client_Traversing ' add event handler that gets called when a significant action occurs during ' the batch transfer (this is optional) AddHandler client.TransferProgressChanged, AddressOf client_TransferProgressChanged ' upload or download files client.Upload(localPath, remotePath, TraversalMode.Recursive) ' of course, the client_ProblemDetected, client_Traversing and client_TransferProgressChanged methods ' have to be implemented - check out the FtpBatchTransfer sample for more information
For more information about these events, check out the FTP Batch Transfer sample application!
Transfer compression - MODE Z
The basic FTP protocol transfers your data as-is without any kind of compression. For highly-compressible
data such as text files or database scripts, this is highly inefficient. To solve this, many FTP servers
introduced MODE Z, an alternative to MODE S and MODE B. In MODE Z, all
transfers are compressed using the ZLIB compression method, making transfers of highly compressible files
(such as TXT, BMP or DOC) much faster - this includes FTP directory listings retrieved using GetList
,
GetRawList
or GetNameList
methods. On the other hand, MODE Z doesn't provide
any substantial speedup for files that are already compresses (such as ZIP, JPEG, PNG or DOCX files).
To enable MODE Z in Rebex FTP, just set the TransferMode
property to
FtpTransferMode.Zlib
.
All data transfers will now use MODE Z if the FTP server supports it and fall back to MODE S if it
doesn't.
// create client, connect and log in Ftp client = new Ftp(); client.Connect("ftp.example.org"); client.Login("username", "password"); // change the preferred transfer mode to MODE Z client.TransferMode = FtpTransferMode.Zlib; // upload the 'hugelist.txt' file to the specified directory at the server client.PutFile(@"c:\data\hugelist.txt", "/wwwroot/hugelist.txt"); // download the 'hugelist.txt' file from the specified directory at the server client.GetFile("/wwwroot/hugelist.txt", @"c:\data\hugelist.txt"); // change the preferred transfer mode to stream mode (default) client.TransferMode = FtpTransferMode.Stream; // upload the 'archive.zip' file to the specified directory at the server client.PutFile(@"c:\data\archive.zip", "/wwwroot/archive.zip"); // download the 'archive.zip' file from the specified directory at the server client.GetFile("/wwwroot/archive.zip", @"c:\data\archive.zip");
' create client, connect and log in Dim client As New Ftp client.Connect("ftp.example.org") client.Login("username", "password") ' change the preferred transfer mode to MODE Z client.TransferMode = FtpTransferMode.Zlib ' upload the 'hugelist.txt' file to the specified directory at the server client.PutFile("c:\data\hugelist.txt", "/wwwroot/hugelist.txt") ' download the 'hugelist.txt' file from the specified directory at the server client.GetFile("/wwwroot/hugelist.txt", "c:\data\hugelist.txt") ' change the preferred transfer mode to stream mode (default) client.TransferMode = FtpTransferMode.Stream ' upload the 'archive.zip' file to the specified directory at the server client.PutFile("c:\data\archive.zip", "/wwwroot/archive.zip") ' download the 'archive.zip' file from the specified directory at the server client.GetFile("/wwwroot/archive.zip", "c:\data\archive.zip")
FtpWebRequest - Pluggable Protocol
There is also an alternative way to using the Ftp
class to upload and download
files using the FTP protocol - the .NET Framework introduced Uri, WebRequest and WebResponse
classes for accessing internet resources through a request/response model and includes
support for HTTP protocol and file:// scheme to request local files.
Rebex FTP for .NET fits nicely into this model with its FtpWebRequest class, which provides an FTP-specific implementation of WebRequest class. Once registered, WebRequest.Create can be used for accessing files on FTP servers in addition to natively supported HTTP and HTTPS.
// register the library for the FTP prefix WebRequest.RegisterPrefix("ftp://", Rebex.Net.FtpWebRequest.Creator); // WebRequest now supports ftp protocol in addition to HTTP/HTTPS // and local files - the rest of this code snippet is protocol-agnostic // create web request for the given URI WebRequest request = WebRequest.Create("ftp://ftp.example.org/files/package.zip"); // get and read web response WebResponse response = request.GetResponse(); Stream stream = response.GetResponseStream(); Stream local = File.Create("package.zip"); byte[] buffer = new byte[1024]; int n; do { n = stream.Read(buffer, 0, buffer.Length); local.Write(buffer, 0, n); } while (n > 0); // close both streams stream.Close(); local.Close();
' register the library for the FTP prefix WebRequest.RegisterPrefix("ftp://", Rebex.Net.FtpWebRequest.Creator) ' WebRequest now supports ftp protocol in addition to HTTP/HTTPS ' and local files - the rest of this code snippet is protocol-agnostic ' create web request for the given URI Dim request As WebRequest = WebRequest.Create("ftp://ftp.example.org/files/package.zip") ' get and read web response Dim response As WebResponse = request.GetResponse() Dim stream As Stream = response.GetResponseStream() Dim local As Stream = File.Create("package.zip") Dim buffer(1023) As Byte Dim n As Integer Do n = stream.Read(buffer, 0, buffer.Length) local.Write(buffer, 0, n) Loop While n > 0 ' close both streams stream.Close() local.Close()
Back to tutorial list...