Skip to content

Search by file pattern functionality in FtpClient #602

Description

@VeritasSoftware

Hi,

Thanks for a great, open source, FTP library.

I was wondering if you could add some search functionality into the FtpClient.

I have created below extensions

image

which allow you to search files by File Patterns like:

* Tax File *.csv

This would match files like:

Robin Tax File 05/25/2020.csv

Usage:

var files = await client.SearchAsync("/tax", "* Tax File *.csv", true);

Something like code below:

using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace FluentFTP
{
    public static class Extensions
    {
        public static async Task<IEnumerable<FtpListItem>> SearchAsync(this FtpClient client,
                                                                       string path, string filePattern, bool recursive = false)
        {
            filePattern = filePattern.Replace(@"\", @"\\")
                                     //escape regex special chars
                                     .RegexReplace(@"([+?|{[()^$#.])", @"\$1")
                                     .Replace("*", ".*?");
            filePattern = $"^{filePattern}$";           

            return await client.SearchFilesAsync(path, filePattern, recursive);
        }

        public static async Task<IEnumerable<FtpListItem>> SearchFilesAsync(this FtpClient client, 
                                                                            string path, string filePatternRegex, 
                                                                            bool recursive = false)
        {
            await client.SetWorkingDirectoryAsync(path);

            var listings = await client.GetListingAsync();

            var files = new List<FtpListItem>();

            if (recursive)
            {
                listings.ToList().ForEach(async item =>
                {
                    if (item.Type == FtpFileSystemObjectType.Directory)
                    {
                        files.AddRange(await client.SearchFilesAsync(item.FullName, filePatternRegex, recursive));
                    }
                });
            }

            files.AddRange(listings.Where(listing => listing.Type == FtpFileSystemObjectType.File &&
                                                        Regex.Match(listing.Name, filePatternRegex, RegexOptions.IgnoreCase | RegexOptions.Compiled).Success));

            return files;
        }

        public static string RegexReplace(this string str, string pattern, string replacement)
        {
            return Regex.Replace(str, pattern, replacement);
        }
    }
}

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions