Search Directory and Sub Folders for Files that contain a certain string and store file paths in ArrayList

Hello All-

I'm in search of a C# function(s) that can search a directory and its sub folders for file(s) that contain a certain string and then store those file(s) full paths in a ArrayList.  So for example if I wanted to find all files that had "ABC123" in their filename and the starting directory was C:\Temp.  C\Temp has multiple subfolders.  Please let me know.  Regards,
JoshinHtownAsked:
Who is Participating?
 
Reza RadConnect With a Mentor Consultant, TrainerCommented:
string[] strFiles=System.IO.Directory.GetFiles(@"C:\temp","*ABC123*",System.IO.SearchOption.AllDirectories)
0
 
Reza RadConsultant, TrainerCommented:
you can do this for both files and directories:

string[] strFiles=System.IO.Directory.GetFiles(@"C:\temp","*ABC123*",System.IO.SearchOption.AllDirectories);
            string[] strDirectories = System.IO.Directory.GetDirectories(@"C:\temp", "*ABC123*", System.IO.SearchOption.AllDirectories);

Open in new window

0
 
JoshinHtownAuthor Commented:
Hello reza_rad-

when I used your code in your first response strFiles did not have any length when I ran it against my required parameters.  When I modified your code to use an ArrayList like below I at least got one count returned.  How can I modify your code below to find every file and add it to ArrayList?

Thanks,


string sMatch = "ABC123";

public void DirSearch(string sMatch)
{
    ArrayList matches = new ArrayList();
    matches.Add(Directory.GetFiles(@"C:\Temp", sMatch, SearchOption.AllDirectories));

    int count = matches.Count;
}
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

 
Reza RadConsultant, TrainerCommented:
try the code I suggested, and use strFiles.Count
Directory.GetFiles or Directory.GetDirectories will return string array, so you should put the result in string[] variable, as I bring it before.
0
 
JoshinHtownAuthor Commented:
hmm this is strange.  I'm still not getting anything loaded into strFiles.  There are at least two files that should get picked up by this code.  Thoughts?
0
 
jfputnamConnect With a Mentor Commented:
Here is a recursive routine that will find all files with a certain pattern in a directory or any of its sub-directories. See the Main for the calling conventions.  The path passed in will have to have the backslashes quoted  i.e. "\\" is one backslash. This was done with Visual Studio 2008  C#




using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace FileSearch
{
    class FileSearch
    {
        //---------------------------------------------------------------------------------------------
        /**
         * loop through a directory of directories, loading all spreadsheets in sub-directories
         * 
         * ---param masterDirectory name of directory of directories
         * ---param file pattern to i.e.  "*.xls"
         * ---param fullFileNames bool if true then full path name is returned else just fileName
         * 
         * ---return List of files found with pattern, or null
         * 
         */
        public ArrayList loadFilesFromDirs(string masterDirectory,String filePattern,bool fullFileNames)
        {
            ArrayList subDirectoryList = getDirListFromDirFiltered(masterDirectory);
            ArrayList fileList = new ArrayList();
            ArrayList retFileList = null;
            ArrayList combinedFileList = null;

            retFileList = getFileListFromDirFiltered(masterDirectory, filePattern, fullFileNames);
            if (retFileList != null) combinedFileList = retFileList;

            foreach (string oneDirName in subDirectoryList)
            {
                FileAttributes f = File.GetAttributes(oneDirName);
                if (f == FileAttributes.Directory)
                {
                    System.Console.WriteLine("----loadFilesFromDirs: directory found, processing dir: " + oneDirName);
                    fileList = loadFilesFromDirs(oneDirName, filePattern, fullFileNames);
                    if (fileList == null)
                    {
                        System.Console.WriteLine("****loadFilesFromDirs: *****bad return from loadFilesFromDirs***** dir: " + oneDirName);
                    }
                    else
                    {
                        combinedFileList.AddRange(fileList);
                    }
                }
                else
                {
                    System.Console.WriteLine("----loadFilesFromDirs: found non-directory, skipping fileName: " + oneDirName);
                }
            } //--end foreach

            return combinedFileList;
        }
        //--------------------------------------------------------------------------------------------
        /**
         * Method that returns a list of files from a Dir
         * 
         * param dirPath string directory path to load files from
         * 
         * return ArrayList of strings of file names
         */
        public static ArrayList getFileListFromDir(string dirPath)
        {
            return getFileListFromDirFiltered(dirPath, "*", false);

        } //--end getFileListFromDir
//--------------------------------------------------------------------------------------------
        /**
         * Method that returns a list of files from a Dir
         * 
         * ---param dirPath string directory path to load files from
         * ---param fileFilter, string to qualify files i.e. *.exe to get only exe files, "" for every
         * ---param fullFileNames bool if true then full path name is returned else just fileName
         * 
         * return ArrayList of strings of file names
         */
        public static ArrayList getFileListFromDirFiltered(string dirPath, string fileFilter,bool fullFileNames)
        {
            ArrayList filesBack = null;
            string useFileFilter = fileFilter;
            string path = null;
            if (fileFilter == null || fileFilter.Trim().Length == 0) useFileFilter = "*.*";
            if (dirPath.Length > 0)
            {
                if (Directory.Exists(dirPath))
                {
                    path = dirPath;
                }
                else
                {
                    //--directory not found;",
                    return null;
                }
                filesBack = new ArrayList();
                DirectoryInfo dir = new DirectoryInfo(path);

                //--loop over all files in the directory filtered by filter string

                foreach (FileInfo f in dir.GetFiles(useFileFilter))
                {
                    String name = f.Name;

                    //---accumulate file names

                    if (fullFileNames) filesBack.Add(dirPath + "\\" + name);
                    else filesBack.Add(name);
                }
            }
            else
            {
                System.Console.WriteLine("---Not dirname--");
                return null;
            }
            return filesBack;

        } //---end getFileListFromDirFiltered
//--------------------------------------------------------------------------------------------
        /**
         * Method that returns a list of subdirectories  from a Dir
         * 
         * param dirPath string directory path to load files from
         * 
         * return ArrayList of strings of subdirectory names names (returs full path names)
         */
        public static ArrayList getDirListFromDirFiltered(string dirPath)
        {
            ArrayList directoriesBack = null;
            string path = null;
            if (dirPath.Length > 0)
            {
                if (Directory.Exists(dirPath))
                {
                    path = dirPath;
                }
                else
                {
                    //--directory not found;",
                    return null;
                }
                directoriesBack = new ArrayList();
                DirectoryInfo dir = new DirectoryInfo(path);

                //--loop over all files in the directory filtered by filter string

                foreach (DirectoryInfo d in dir.GetDirectories())
                {
                    String name = d.FullName;

                    //---accumulate file names

                    directoriesBack.Add(name);
                }
            }
            else
            {
                System.Console.WriteLine("---Not dirname--");
                return null;
            }
            return directoriesBack;

        } //---end getFileListFromDirFiltered
//----------------------------------------------------------------------------------------------------------------------
        static void Main(string[] args)
        {
            FileSearch myApp = new FileSearch();
            string dirStart = "c:\\testdir";
            string filePattern = "*.abc";

            ArrayList fileList = null;
            bool fullFileNames = true;

            fileList = myApp.loadFilesFromDirs(dirStart, filePattern,fullFileNames);

            foreach (string fileName in fileList)
            {
                System.Console.WriteLine(" fileName: " + fileName);
            }
        }
    }
}

Open in new window

0
 
JoshinHtownAuthor Commented:
Hi jfputnam-

I tried your code as well and setup my parameters in the Main while making sure I had C:\\Temp.  I placed breakpoints in loadFilesFromDirs because I noticed it was entering the last Else suggesting it a non-directory or that it was skipping that fileName.  Inside C:\\Temp there is a folder called Arkansas that it skips but I cannot understand why.  The files I need returned are inside this folder.  The file pattern will vary.
0
 
Shahan AyyubSenior Software Engineer - iOSCommented:
Hi try the below code:

Here: 'PathofRootDir' simple means,as you mentioned: C:\temp\
i.e. 'temp' and all its subfolders.

and will return you an ArrayList of those files' path which you want to save. :)
public static ArrayList SearchAndSave(string Filename, string PathofRootDir)
        {
         ArrayList Al=new ArrayList(Directory.GetFiles(PathofRootDir, "*.*", SearchOption.AllDirectories));
         return Al;
        }

Open in new window

0
 
Shahan AyyubSenior Software Engineer - iOSCommented:
Oooops, I forgot to use the parameter Filename :O
0
 
jfputnamCommented:
Does the same folder get excluded with all techiques you have tried?
0
 
JoshinHtownAuthor Commented:
Jfputman-

I see where your code is failing on my end.  Inside getFileListFromDirFiltered at the very bottom where your below foreach loop is.  Whenever it hits the first dir.GetFiles(useFileFilter) and then tries to jump to FileInfo f before entering loop it just fails.  useFileFilter is set to ABC123 which is what I'm looking for in any file name within these folders.  Two Files should get returned but none do through this code.  Any thoughts?

 foreach (FileInfo f in dir.GetFiles(useFileFilter))
                {
                    String name = f.Name;

                    //---accumulate file names

                    if (fullFileNames) filesBack.Add(dirPath + "\\" + name);
                    else filesBack.Add(name);
                }
0
 
Shahan AyyubConnect With a Mentor Senior Software Engineer - iOSCommented:
I apologize you for the mismatch post. Try the below code:

Here: 'PathofRootDir' simple means,as you mentioned: C:\temp\
i.e. 'temp' and all its subfolders.

and will return you an ArrayList of those files' path which you want to save.
public static ArrayList SearchAndSave(string Filename, string PathofRootDir)
        {
            ArrayList Al=new ArrayList();
            Regex re = new Regex("^" + Filename + "$");

            string[] Files = Directory.GetFiles(PathofRootDir, "*", SearchOption.AllDirectories);

            foreach (string path in Files)
            {
                string[] tempFile = path.Split('\\');
                if (re.IsMatch(tempFile[tempFile.Length-1]))
                    Al.Add(path);
            }
            return Al;
        }

Open in new window

0
 
jfputnamCommented:
Josh I just put in some files ABC123 in several sub directories and if found every one. Do you have file extents hidden. If so then maybe you want to use pattern "ABC123*" or "ABC123.*"
0
 
JoshinHtownAuthor Commented:
I ended up getting this working with the very first post from reza_rad.  I had left off the Stars on the search string, sorry reza.  Some of y'all had me going in the right direction as well as I was getting farther through your code so I will accept multiple solutions but reza got me finished.  Thank you everyone.
0
 
Shahan AyyubSenior Software Engineer - iOSCommented:
Josh if you have filename like:


>      2ABC2.txt
>      2ABC.txt

and you need ABC.txt you will need a mismatch in reza's post :)
0
 
JoshinHtownAuthor Commented:
really?  I just tested it and it seemed to return the two files I needed just fine and they had extra characters in them.  I will post another thread or try to get y'alls code working if reza's doesn't work but it seems to work
0
 
Shahan AyyubSenior Software Engineer - iOSCommented:
I will recommend you to use Regular expression for the matching of filenames. It will always give you the correct result.
You can use this regular expression as i posted:

            Regex re = new Regex("^" + Filename + "$");


-Shahan
0
 
JoshinHtownAuthor Commented:
Thanks Shahan-  I will definitely make notes of your regular expression and everyone elses comments on here.  I posted as many points as I could to give everyone points.  Thanks again everyone.
0
 
Shahan AyyubSenior Software Engineer - iOSCommented:
JoshinHtown, points doesn't matter, I just want you to go into positive direction.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.