FluentFTP icon indicating copy to clipboard operation
FluentFTP copied to clipboard

Search by file pattern functionality in FtpClient

Open VeritasSoftware opened this issue 5 years ago • 0 comments

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);
        }
    }
}

VeritasSoftware avatar Jul 25 '20 01:07 VeritasSoftware