More .NET libraries
-
Rebex SFTP
.NET SFTP client
-
Rebex File Transfer Pack
FTP/SSL and SFTP together
-
Rebex Total Pack
All Rebex .NET libraries together
Back to feature list...
More file transfer operations
On this page:
- Resuming interrupted transfers
- Overwriting existing files
- Auto-renaming existing files
- Progress reporting
- Transfer problem handling
- Restoring date&time after transfer
- ASCII and binary transfer modes
- Active and passive transfer modes
- ZLIB transfer compression (MODE Z)
- Block mode support (MODE B) - reusable data channel
- Large file support
Resuming interrupted transfers
When a connection is lost or aborted, you may end up with incompletely transferred file. Instead of transferring in all over again, it's possible to resume the operation and only transfer the missing part.
Upload
and Download
methods can do this - just specify ActionOnExistingFiles.ResumeIfPossible
when calling. This will:
- transfer files which were not transferred yet (don't exist at the destination)
- transfer remaining parts of files which are smaller at the destination than on source
- skip all other files
// auto-resume failed directory upload ftp.Upload(@"C:\MyData\*", "/MyData", 0, 0, ActionOnExistingFiles.ResumeIfPossible); // auto-resume failed single file download ftp.Download("/MyData/file.txt", @"C:\MyData", 0, 0, ActionOnExistingFiles.ResumeIfPossible);
' auto-resume failed directory upload ftp.Upload("C:\MyData\*", "/MyData", 0, 0, ActionOnExistingFiles.ResumeIfPossible) ' auto-resume failed single file download ftp.Download("/MyData/file.txt", "C:\MyData", 0, 0, ActionOnExistingFiles.ResumeIfPossible)
ResumeIfPossible
will not re-establish interrupted transfer automatically.
If transfer is aborted, you have to re-establish connection and start transfer with ResumeIfPossible
manually.
Overwriting existing files
When transferring multiple files using Upload
or Download
method,
use ActionOnExistingFiles
argument to specify what to do when a target file already exists.
To overwrite existing files, use one of these options:
OverwriteAll
- Overwrites all files.OverwriteOlder
- Overwrites files which are older that source files.OverwriteDifferentSize
- Overwrites files which have different size.OverwriteDifferentChecksum
- Overwrites files which have different checksum.
Note: Only some FTP servers support checksums.
Alternatively, in order not to overwrite existing files, use one of these instead:
SkipAll
- Skip files.ResumeIfPossible
- Resume the transfer if possible.Rename
- Rename files using "filename[number].extension" pattern.ThrowException
- Fail with an error.
ActionOnExistingFiles
argument specifies default behavior.
However, you can still override it using ProblemDetected
event.
// set desired overwrite mode according to a .config file ActionOnExistingFiles action = ActionOnExistingFiles.ThrowException; switch (ConfigurationManager.AppSettings["OverwriteMode"]) { case "skip": action = ActionOnExistingFiles.SkipAll; break; case "all": action = ActionOnExistingFiles.OverwriteAll; break; case "older": action = ActionOnExistingFiles.OverwriteOlder; break; case "size": action = ActionOnExistingFiles.OverwriteDifferentSize; break; case "checksum": action = ActionOnExistingFiles.OverwriteDifferentChecksum; break; } // upload directory with specific overwrite mode ftp.Upload(@"C:\MyData\*", "/MyData", 0, 0, action);
' set desired overwrite mode according to a .config file Dim action = ActionOnExistingFiles.ThrowException Select Case ConfigurationManager.AppSettings("OverwriteMode") Case "skip" : action = ActionOnExistingFiles.SkipAll Case "all" : action = ActionOnExistingFiles.OverwriteAll Case "older" : action = ActionOnExistingFiles.OverwriteOlder Case "size" : action = ActionOnExistingFiles.OverwriteDifferentSize Case "checksum" : action = ActionOnExistingFiles.OverwriteDifferentChecksum End Select ' upload directory with specific overwrite mode ftp.Upload("C:\MyData\*", "/MyData", 0, 0, action)
Auto-renaming existing files
When transferring multiple files using Upload
or Download
method,
specify the ActionOnExistingFiles.Rename
argument to automatically rename transferred
file if the target file already exists. This will add a number between the filename and extension ("filename[number].extension" pattern).
ProblemDetected
event instead.
// upload directory, // auto-rename transferred files // if target file already exists ftp.Upload(@"C:\MyData\*", "/MyData", 0, 0, ActionOnExistingFiles.Rename); // download file, // rename it if "C:\MyData\file.txt" already exists // (e.g., "C:\MyData\file[1].txt" might be created) ftp.Download("/MyData/file.txt", @"C:\MyData", 0, 0, ActionOnExistingFiles.Rename);
' upload directory, ' auto-rename transferred files ' if target file already exists ftp.Upload("C:\MyData\*", "/MyData", 0, 0, ActionOnExistingFiles.Rename) ' download file, ' rename it if "C:\MyData\file.txt" already exists ' (e.g., "C:\MyData\file[1].txt" might be created) ftp.Download("/MyData/file.txt", "C:\MyData", 0, 0, ActionOnExistingFiles.Rename)
Progress reporting
Displaying progress of both single-file and multi-file transfers is simple with TransferProgressChanged
event. It keeps you updated with:
ProgressPercentage
- percentage of the whole operation that has been completed (useful when transferring multiple files)CurrentFileProgressPercentage
- percentage of the current file that has been transferredBytesPerSecond
- approximate current transfer speedAction
- current action (upload or download)SourceItem
- information about the currently processed itemTransferState
- current operation state (processing file or directory, data block, whole file transferred, ...)- And much more (
TargetPath
,FilesProcessed
,FilesTotal
, ...)
Traversing
event.
Sample transfer progress event handler:
System.Windows.Forms.ProgressBar fileProgressBar; System.Windows.Forms.ProgressBar totalProgressBar; System.Windows.Forms.Label transferSpeedLabel; void client_TransferProgressChanged(object sender, FtpTransferProgressChangedEventArgs e) { // update ProgressBar of the current file fileProgressBar.Value = (int)e.CurrentFileProgressPercentage; // update ProgressBar of the whole transfer totalProgressBar.Value = (int)e.ProgressPercentage; // update transfer speed transferSpeedLabel.Text = e.BytesPerSecond.ToString(); }
Dim fileProgressBar As System.Windows.Forms.ProgressBar Dim totalProgressBar As System.Windows.Forms.ProgressBar Dim transferSpeedLabel As System.Windows.Forms.Label Sub client_TransferProgressChanged(ByVal sender As Object, ByVal e As FtpTransferProgressChangedEventArgs) ' update ProgressBar of the current file fileProgressBar.Value = e.CurrentFileProgressPercentage ' update ProgressBar of the whole transfer totalProgressBar.Value = e.ProgressPercentage ' update transfer speed transferSpeedLabel.Text = e.BytesPerSecond.ToString() End Sub
Registering the event:
// register TransferProgressChanged event handler which is raised // when a significant action occurs ftp.TransferProgressChanged += client_TransferProgressChanged; // transfer files // ...
' register TransferProgressChanged event handler which is raised ' when a significant action occurs AddHandler ftp.TransferProgressChanged, AddressOf client_TransferProgressChanged ' transfer files ' ...
Transfer problem handling
When a problem occurs in Upload
or Download
method, your code can get notified about it using
the ProblemDetected
event and react accordingly.
See TransferProblemType
enum for a list of possible problems you can handle.
The FtpProblemDetectedEventArgs
argument of the event
makes it possible to determine what is going on and choose an appropriate reaction.
These are some of the properties available:
Exception
- an exception (if any) which will be raised if the problem is not handledProblemType
- the kind of problem that has occuredAction
- current action (upload, download, ...)Reaction
- selected reaction (fail, skip, overwrite, ...)
Sample ProblemDetected event handler
The following code shows a ProblemDetected
event handler
that provides a custom 'FileExists' problem handling:
- Already-existing ".txt" files are renamed
- Other already-existing files are overwritten, but only if they are older than 7 days
- All other problems will be handled using the default behavior (see below)
void client_ProblemDetected(object sender, FtpProblemDetectedEventArgs e) { // handle only existing files problem if (e.ProblemType != TransferProblemType.FileExists) return; // rename ".txt" files if (Path.GetExtension(e.LocalPath) == ".txt") { e.Rename(); return; } // initialize source and target dates (use whole date granularity) DateTime source = e.LocalItem.LastWriteTime.Value.Date; DateTime target = e.RemoteItem.LastWriteTime.Value.Date; // overwrite files which are older than 7 days if (source > target && target < DateTime.Now.AddDays(-7)) { e.Overwrite(); return; } }
Sub client_ProblemDetected(ByVal sender As Object, ByVal e As FtpProblemDetectedEventArgs) ' handle only existing files problem If e.ProblemType <> TransferProblemType.FileExists Then Return ' rename ".txt" files If Path.GetExtension(e.LocalPath) = ".txt" Then e.Rename() Return End If ' initialize source and target dates (use whole date granularity) Dim source = e.LocalItem.LastWriteTime.Value.Date Dim target = e.RemoteItem.LastWriteTime.Value.Date ' overwrite files which are older than 7 days If source > target AndAlso target < DateTime.Now.AddDays(-7) Then e.Overwrite() Return End If End Sub
Registering the event and setting the default behavior:
// register ProblemDetected event handler which is raised // when target file already exists (besides other things) ftp.ProblemDetected += client_ProblemDetected; // upload directory (skip existing files by default) ftp.Upload(@"C:\MyData\*", "/MyData", 0, 0, ActionOnExistingFiles.SkipAll);
' register ProblemDetected event handler which is raised ' when target file already exists (besides other things) AddHandler ftp.ProblemDetected, AddressOf client_ProblemDetected ' upload directory (skip existing files by default) ftp.Upload("C:\MyData\*", "/MyData", 0, 0, ActionOnExistingFiles.SkipAll)
Restoring date&time after transfer
By default, file times (creation, last access or last write time) are not synchronized after a successful file transfer.
Use Settings.RestoreDateTime
property to enable file time synchronization.
// set to restore last modified time ftp.Settings.RestoreDateTime = ItemDateTimes.LastWriteTime; // transfer files // ...
' set to restore last modified time ftp.Settings.RestoreDateTime = ItemDateTimes.LastWriteTime ' transfer files ' ...
FTP protocol supports LastWriteTime only (CreationTime and LastAccessTime are not supported).
Please note that the time granularity of FTP server and local file system can differ. For example, many FTP servers ignore the millisecond part of file date/time.
Different time zones on client and server can cause discrepancies as well with some FTP servers. Check out a blog post about handling file modification date/time in FTP for more information.
ASCII and binary transfer modes
The default transfer mode is binary, which means data is transferred as is without any processing. However, when transferring text data between platforms which use different end-of-line sequences (Windows use <CR><LF> Unix uses <LF>), it's useful to have the sequences automatically converted by setting the transfer mode to ASCII.
Use TransferType
property to specify the desired transfer type.
// set transfer type to ASCII ftp.TransferType = FtpTransferType.Ascii; // transfer files // ...
' set transfer type to ASCII ftp.TransferType = FtpTransferType.Ascii ' transfer files ' ...
Active and passive transfer modes
Passive transfer mode is used by default because it operates nicely with most firewalls.
To use Active transfer mode, set Passive
property to false
.
// set to active transfers ftp.Passive = false; // transfer files // ...
' set to active transfers ftp.Passive = False ' transfer files ' ...
ZLIB transfer compression (MODE Z)
FTP protocol supports ZLIB compression to speed up data transfers. This is particularly useful when transferring highly compressible data such as text files or sparse files. However, it can slow down the transfer speed slightly for already-compressed, multimedia or less compressible files.
// set transfer compression ftp.TransferMode = FtpTransferMode.Zlib; // transfer files // ...
' set transfer compression ftp.TransferMode = FtpTransferMode.Zlib ' transfer files ' ...
Block mode support (MODE B) - reusable data channel
In stream mode (default), each data transfer requires opening and closing the data connection.
In block mode blocks of data are sent with a header that makes it possible to reuse the data connection for subsequent transfers.
However, block mode is only supported by several FTP servers (IIS 7.0+ or WFTPD Pro).
// set block mode ftp.TransferMode = FtpTransferMode.Block; // transfer files // ...
' set block mode ftp.TransferMode = FtpTransferMode.Block ' transfer files ' ...
Large file support
Rebex FTP/SSL supports very large files - the theoretical maximum file size supported by the FTP protocol is 2^63 bytes, which is 9,223,372,036,854,775,807, or 9,223,372 TB.
However, in practice, the maximum file size might limited by the underlying filesystem.
For example, FAT16
's maximum file size is 2GB
, FAT32
's limit is 4GB
.
Check out this table for other filesystems.
But is it possible to transfer files larger than 4GB
even when the local filesystem can't store them?
Actually, it is - you can use the stream-based API, which makes it possible to develop a custom stream to work around the filesystem's limitation (by splitting data into multiple smaller files, for example).
Back to feature list...