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...
Directory operations
On this page:
- Working with current directory
- Listing directory content
- Listing directory content - recursively
- Listing directory content - on the fly
- Getting raw directory listing
- Finding files
- Creating a directory
- Deleting a directory
- Deleting directories recursively
- Renaming/moving a directory
- Checking directory existence
- Sorting directory content
- LINQ support - IEnumerable<T> collection
- Powerful directory listing parser
- Custom directory listing parsers
Working with current directory
To get current directory, use GetCurrentDirectory
method. To change it, use ChangeDirectory
method.
// set current directory ftp.ChangeDirectory("/MyData"); // display the current directory to the user string currentDir = ftp.GetCurrentDirectory(); Console.WriteLine("Current directory changed to: {0}", currentDir);
' set current directory ftp.ChangeDirectory("/MyData") ' display the current directory to the user Dim currentDir As String = ftp.GetCurrentDirectory() Console.WriteLine("Current directory changed to: {0}", currentDir)
Listing directory content
To retrieve listings of directory content, three methods are available:
GetList
- returns collection ofFtpItem
objectsGetNameList
- returns aString
array of item namesGetRawList
- returns aString
array of item information in server-specific format (see more)
ChangeDirectory
first to select the target directory and then
call the argument-less variant of a Get*List method.
// get items within the current directory FtpItemCollection currentItems = ftp.GetList(); // get names of items within "/MyData string[] dataItems = ftp.GetNameList("/MyData"); // get server-specific listing of all ".txt" files in "/MyData" string[] dataTextFiles = ftp.GetRawList("/MyData/*.txt");
' get items within the current directory Dim currentItems As FtpItemCollection = ftp.GetList() ' get names of items within "/MyData Dim dataItems As String() = ftp.GetNameList("/MyData") ' get server-specific listing of all ".txt" files in "/MyData" Dim dataTextFiles As String() = ftp.GetRawList("/MyData/*.txt")
GetItems
method.See comparison of Get*List and GetItems methods.
Listing directory content - recursively
To retrieve a listing of directory content including items in subdirectories,
or to use more complex filtering criteria, use GetItems
method.
TraversalMode
and Rebex.IO.FileSet
features.
FtpItemCollection items; // get all items of current directory recursively // (items from subdirectories are returned as well) items = ftp.GetItems("*"); // get all ".txt" files of "/MyData" directory only // (files from subdirectories are not returned) items = ftp.GetItems("/MyData/*.txt", TraversalMode.MatchFilesShallow); // get all ".txt" files under "/MyData" directory // (files from subdirectories are returned as well) items = ftp.GetItems("/MyData/*.txt", TraversalMode.MatchFilesDeep); // initialize a file set var fileSet = new Rebex.IO.FileSet("/MyData"); fileSet.Include("Web"); fileSet.Exclude("Web/Images"); // get all items defined by the file set items = ftp.GetItems(fileSet);
Dim items As FtpItemCollection ' get all items of current directory recursively ' (items from subdirectories are returned as well) items = ftp.GetItems("*") ' get all ".txt" files of "/MyData" directory only ' (files from subdirectories are not returned) items = ftp.GetItems("/MyData/*.txt", TraversalMode.MatchFilesShallow) ' get all ".txt" files under "/MyData" directory ' (files from subdirectories are returned as well) items = ftp.GetItems("/MyData/*.txt", TraversalMode.MatchFilesDeep) ' initialize a file set Dim fileSet = New Rebex.IO.FileSet("/MyData") fileSet.Include("Web") fileSet.Exclude("Web/Images") ' get all items defined by the file set items = ftp.GetItems(fileSet)
GetItems
(as well as other multiple files operations)
would not work properly on those FTP servers, which cannot resolve existence of files or directories (some mainframe systems etc.).
Listing directory content - on the fly
All item listing methods raise a ListItemReceived
event when an item is received.
This is very useful when working with huge directory listings because it makes it possible to display items as they arrive.
It also makes it possible to filter item listings using any custom criteria (such as last write time).
Custom item listing filter implementation:
void client_ListItemReceived(object sender, FtpListItemReceivedEventArgs e) { // ignore ale items older than 7 days if (e.Item.LastWriteTime < DateTime.Now.Date.AddDays(-7)) e.Ignore(); }
Sub client_ListItemReceived(ByVal sender As Object, ByVal e As FtpListItemReceivedEventArgs) ' ignore ale items older than 7 days If e.Item.LastWriteTime < DateTime.Now.Date.AddDays(-7) Then e.Ignore() End If End Sub
Registering the event handler:
// register ListItemReceived event handler which is raised // when an item description is received from the server ftp.ListItemReceived += client_ListItemReceived; // get items of current directory filtered by the event handler FtpItemCollection items = ftp.GetList();
' register ListItemReceived event handler which is raised ' when an item description is received from the server AddHandler ftp.ListItemReceived, AddressOf client_ListItemReceived ' get items of current directory filtered by the event handler Dim items As FtpItemCollection = ftp.GetList()
Getting raw directory listing
The GetRawList
method provides a list of files and directories in a server-specific text format.
The format strongly depends on the FTP server:
Sample raw list from the Microsoft IIS FTP server:
06-21-13 10:48AM 17 file.pdf 06-21-13 10:48AM 17 file.txt 06-21-13 10:48AM <DIR> Web
Sample raw list from the Wu-FTPd server:
drwxr-xr-x 2 root root 4096 Aug 3 2012 dir lrwxrwxrwx 1 root root 8 Aug 3 2012 slink -> test.txt -rw-r--r-- 2 root root 18 Aug 3 2012 test.txt
Code example
// get server-specific listing of items within the current directory string[] currentItems = ftp.GetRawList(); // get server-specific listing of text files within the specified directory string[] textFiles = ftp.GetRawList("/MyData/*.txt"); // simply print the directory listing Console.WriteLine(string.Join("\r\n", currentItems));
' get server-specific listing of items within the current directory Dim currentItems As String() = ftp.GetRawList() ' get server-specific listing of text files within the specified directory Dim textFiles As String() = ftp.GetRawList("/MyData/*.txt") ' simply print the directory listing Console.WriteLine(String.Join(vbCrLf, currentItems))
Finding files
To find a file or multiple files on the remote host, use GetList
and GetItems
methods.
The GetList
method only searching in one particular folder, while GetItems
method
can search its subfolders as well:
FtpItemCollection items; // find all "*.txt" files in "/MyData" directory only items = ftp.GetList("/MyData/*.txt"); // find all "*.txt" files in "/MyData" directory and its subdirectories items = ftp.GetItems("/MyData/*.txt", TraversalMode.MatchFilesDeep);
Dim items As FtpItemCollection ' find all "*.txt" files in "/MyData" directory only items = ftp.GetList("/MyData/*.txt") ' find all "*.txt" files in "/MyData" directory and its subdirectories items = ftp.GetItems("/MyData/*.txt", TraversalMode.MatchFilesDeep)
Each of these approaches has its pitfalls:
GetList
method's argument processing is server specific. Use wildcards inGetList
method only if you are sure your FTP server supports it well.GetItems
method's filtering is performed on client side. When searching even a single file in a large directory hierarchy, a significant amount of time should be considered for loading the directory structure.GetItems
method (just like other multiple files operations) won't work properly on FTP servers that don't present a Unix-like filesystem (such as some mainframe systems).
Creating a directory
To create a new remote directory, use CreateDirectory
method.
On well-behaved FTP servers, the it returns the absolute path of the newly created directory.
// create new remote directory string newDir = ftp.CreateDirectory("/MyData/Exports"); // diplay the result Console.WriteLine("New directory created: {0}", newDir);
' create new directory Dim newDir As String = ftp.CreateDirectory("/MyData/Exports") ' display the result Console.WriteLine("New directory created: {0}", newDir)
Deleting a directory
To delete an empty remote directory, use RemoveDirectory
method.
Delete
method instead.
// delete remote directory if it doesn't exist locally if (!Directory.Exists(@"C:\MyData\Exports")) { // fails if not empty ftp.RemoveDirectory("/MyData/Exports"); // notify the user // ... }
' delete remote directory if it doesn't exist locally If Not Directory.Exists("C:\MyData\Exports") Then ' fails if not empty ftp.RemoveDirectory("/MyData/Exports") ' notify the user ' ... End If
Deleting directories recursively
To delete non-empty remote directory or multiple files, use Delete
method.
Be careful - this is a very powerful method.
// delete whole remote directory // (deletes "/MyData/Temp" directory itself as well) ftp.Delete("/MyData/Temp", TraversalMode.Recursive); // delete content of remote directory // (keep "/MyData" directory itself) ftp.Delete("/MyData/*", TraversalMode.Recursive); // delete all ".txt" files in "/MyData" ftp.Delete("/MyData/*.txt", TraversalMode.MatchFilesShallow);
' delete whole remote directory ' (deletes "/MyData/Temp" directory itself as well) ftp.Delete("/MyData/Temp", TraversalMode.Recursive) ' delete content of remote directory ' (keep "/MyData" directory itself) ftp.Delete("/MyData/*", TraversalMode.Recursive) ' delete all ".txt" files in "/MyData" ftp.Delete("/MyData/*.txt", TraversalMode.MatchFilesShallow)
Renaming/moving a directory
To rename a directory, use Rename
method.
It can be used for moving a remote directory to another location at the server as well.
// rename a remote directory ftp.Rename("/MyData/A", "/MyData/B"); // move a remote directory ftp.Rename("/MyData/Exports", "/Backups/Exports");
' rename a remote directory ftp.Rename("/MyData/A", "/MyData/B") ' move a remote directory ftp.Rename("/MyData/Exports", "/Backups/Exports")
Tip: For moving directories between a client and a server,
use Upload
or Download
methods with TransferMethod.Move
argument.
Checking directory existence
To check whether a remote directory already exists, use DirectoryExists
method.
// check whether a remote directory exists bool exists = ftp.DirectoryExists("/MyData/Exports"); if (exists) { // prompt the user // ... }
' check whether a remote directory exists Dim exists = ftp.DirectoryExists("/MyData/Exports") If exists Then ' prompt the user ' ... End If
DirectoryExists
tries several ways to check whether the file exists
and works well with almost all FTP servers, it may fail on some legacy FTP servers with a "not supported" exception.
Sorting directory content
GetList
and GetItems
methods return directory items in the
same order as returned by the server, which often means no sorting at all.
To sort the items, use FtpItemCollection
's Sort
method
and FileSystemItemComparer
object.
FileSystemItemComparerType
enum.
// get items in the current directory FtpItemCollection items = ftp.GetList(); // example 1: large files first items.Sort(new FileSystemItemComparer(FileSystemItemComparerType.Length)); // example 2: order by multiple fields // (directories first, then order by file name) items.Sort(new MultiComparer( new FileSystemItemComparer(FileSystemItemComparerType.FileType), new FileSystemItemComparer(FileSystemItemComparerType.Name)));
' get items in the current directory Dim items As FtpItemCollection = ftp.GetList() ' example 1: large files first items.Sort(New FileSystemItemComparer(FileSystemItemComparerType.Length)) ' example 2: order by multiple fields ' (directories first, then order by file name) items.Sort(New MultiComparer( New FileSystemItemComparer(FileSystemItemComparerType.FileType), New FileSystemItemComparer(FileSystemItemComparerType.Name)))
LINQ support - IEnumerable<T> collection
The FtpItemCollection
object returned by GetList
and GetItems
methods
implements IEnumerable<FtpItem>
to support LINQ queries:
As it implements IEnumerable<FileSystemItem>
as well (part of common FTP and FTP API),
casting it explicitly to IEnumerable<FtpItem>
might be necessary in order to use the proper LINQ extension methods.
You can achieve this by calling Cast<FtpItem>
method.
DateTime dt = DateTime.Now.Date.AddDays(-7); // get all ".txt" files not older than 7 days sorted by path // from current directory using LINQ methods var files1 = ftp.GetList("*.txt").Cast<FtpItem>(). Where(item => item.IsFile && item.LastWriteTime > dt). OrderBy(item => item.Path); // get all ".txt" files not older than 7 days sorted by path // anywhere under current directory using a LINQ query var items = ftp.GetItems("*.txt", TraversalMode.MatchFilesDeep); var files2 = from FtpItem item in items where item.IsFile && item.LastWriteTime > dt orderby item.Path select item;
Dim dt = DateTime.Now.Date.AddDays(-7) ' get all ".txt" files not older than 7 days sorted by path ' from current directory using LINQ Dim files1 = ftp.GetList("*.txt").Cast(Of FtpItem). Where(Function(item) item.IsFile AndAlso item.LastWriteTime > dt). OrderBy(Function(item) item.Path) ' get all ".txt" files not older than 7 days sorted by path ' anywhere under current directory using LINQ to SQL Dim items = ftp.GetItems("*.txt", TraversalMode.MatchFilesDeep) Dim files2 = From item As FtpItem In items Where item.IsFile AndAlso item.LastWriteTime > dt Order By item.Path Select item
Powerful directory listing parser
The original FTP protocol defined no standard directory listing format. Although most modern FTP servers support a MLST format intended for machine processing, there are many FTP servers still in use that only support a human-readable listing format (see examples). Fortunately, Rebex FTP/SSL features a powerful listing parser that can parse almost all the various listing formats into a collection of well structured FtpItem objects, making the name, size, modified time or type accessible as strongly-typed properties.
Custom directory listing parsers
If you encounter an FTP server with a rare listing format not supported by Rebex parsers, you can easily add a parser for it:
// sample of custom directory item parser method private static void MyDirectoryItemParser(object sender, FtpItemParseEventArgs e) { // if the item has a valid name, return the original item if (e.Item != null || !string.IsNullOrEmpty(e.Item.Name)) return; // a very simple sample of parsing item from the raw list string parsedName = e.RawLine.Substring(39); bool parsedDirectory = e.RawLine.Contains("<DIR>"); // create a new item and fill it with parsed values e.Item = new FtpItem( parsedName, 0, parsedDirectory ? FtpItemType.Directory : FtpItemType.File); }
' sample of custom directory item parser method Private Sub MyDirectoryItemParser(ByVal sender As Object, ByVal e As FtpItemParseEventArgs) ' if the item has a valid name, return the original item If Not e.Item Is Nothing And Not String.IsNullOrEmpty(e.Item.Name) Then Return End If ' a very simple sample of parsing item from the raw list Dim parsedName = e.RawLine.Substring(39) Dim parsedType = FtpItemType.File If e.RawLine.Contains("<DIR>") Then parsedType = FtpItemType.Directory End If ' create a new item and fill it with parsed values e.Item = New FtpItem(parsedName, 0, parsedType) End Sub
Register the parser as a static event handler:
// register the custom parser to the FtpItem class FtpItem.ItemParse += MyDirectoryItemParser; // get the directory listing using the new parser foreach (var item in ftp.GetList()) Console.WriteLine("{0} {1}", item.Name, item.IsDirectory ? " <dir>" : "");
' register the custom parser to the FtpItem class AddHandler FtpItem.ItemParse, AddressOf MyDirectoryItemParser ' get the directory listing using the new parser For Each item In ftp.GetList() Console.WriteLine("{0} dir={1}", item.Name, item.IsDirectory) Next
Back to feature list...