Author Topic: Findfile recursive ..  (Read 11492 times)

0 Members and 1 Guest are viewing this topic.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Findfile recursive ..
« on: December 19, 2008, 09:09:46 PM »
FindFile in the net API is handy ... as it is in lisp ... but the limiting search folders is sometimes a restraint

... think of the case where you know the file you want is nested in a tree structure and because of dynamics you may not know the location.

This code is beta, but seems to do the job.

This is the tree I'm looking at .. the tree structure is dynamic but I know the file I want is in there somewhere.



First try a findfile with the qualified Path

Then some recursion variations ..

Code: [Select]
        [CommandMethod("Cmd2")]
        static public void test2()
        {
            Database db = HostApplicationServices.WorkingDatabase;
            Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
            string fileName = @"F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0341\Squircle.dwg";
     
            ed.WriteMessage("\n\n ----------- FindFile(... " );
            string qualifiedPath = HostApplicationServices.Current.
                            FindFile(fileName, db, FindFileHint.Default);
            if (string.IsNullOrEmpty(qualifiedPath))
            {
                ed.WriteMessage("\nOooops, Can't find file " + fileName);
            } else
            {
                ed.WriteMessage("\nFile Found at " + qualifiedPath);
            }
            /////
            ed.WriteMessage("\n\n ----------- FindFilesRecursive(...  " + "*.*" );
            List<string> fileList1 = FindFilesRecursive(@"F:\_kdub_testing", "*.*");
            foreach (string s in fileList1)
            {
                ed.WriteMessage("\n" + s);
            }
            /////
            ed.WriteMessage("\n\n ----------- FindFilesRecursive(...  " + "*.txt" );
            List<string> fileList2 = FindFilesRecursive(@"F:\_kdub_testing", "*.txt");
            foreach (string s in fileList2)
            {
                ed.WriteMessage("\n" + s);
            }
            /////
            ed.WriteMessage("\n\n ----------- FindFilesRecursive(...  " + "*nest*" );
            List<string> fileList3 = FindFilesRecursive(@"F:\_kdub_testing", "*nest*");
            foreach (string s in fileList3)
            {
                ed.WriteMessage("\n" + s);
            }
            /////
            ed.WriteMessage("\n\n ----------- FindFilesRecursive(...  " + "Squircle.dwg" );
            List<string> fileList4 = FindFilesRecursive(@"F:\_kdub_testing", "*Squircle.dwg");
            foreach (string s in fileList4)
            {
                ed.WriteMessage("\n" + s);
            }
            /////
            ed.WriteMessage("\n\n ----------- FindFilesRecursive(...  " + "SQUIRCLE.dwg" );
            List<string> fileList5 = FindFilesRecursive(@"F:\_kdub_testing", "SQUIRCLE.dwg");
            foreach (string s in fileList5)
            {
                ed.WriteMessage("\n" + s);
            }
            /////
        }



        static List<string> FindFilesRecursive(string initialFolder, string searchPattern)
        {         
            // declare the file results list.
            List<string> resultList = new List<string>();

            // declare dynamic stack of folders.
            Stack<string> folderStack = new Stack<string>();

            // Add initialFolder to stack.
            folderStack.Push(initialFolder);

            // while there are Folders and child-Folders on the stack ...
            while (folderStack.Count > 0)
            {               
                // remove the top Folder name from the stack and
                // see what the folder contains ....
                string dir = folderStack.Pop();
                try
                {                   
                    // Add all files for/in this folder to the result List.
                    resultList.AddRange(Directory.GetFiles(dir, searchPattern));
                   
                    // Add all sub-folders for/in this folder to the Stack.
                    foreach (string dn in Directory.GetDirectories(dir))
                    {
                        folderStack.Push(dn);
                    }
                } catch
                {                   
                    // problem opening folder
                }
            }
            return resultList;
        }   



... and the results ..

Quote
Command: netload

Command: cmd2


 ----------- FindFile(...
File Found at F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0341\Squircle.dwg

 ----------- FindFilesRecursive(...  *.*
F:\_kdub_testing\nest-0\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\cross.dwg
F:\_kdub_testing\nest-0\nest-03\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-035\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-035\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0342\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0342\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0341\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0341\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0341\Squircle.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0341\squircle.txt
F:\_kdub_testing\nest-0\nest-03\nest-033\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-033\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-032\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-032\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-032\nest-0322\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-032\nest-0322\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-032\nest-0321\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-032\nest-0321\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-031\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-031\cross.dwg
F:\_kdub_testing\nest-0\nest-02\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\nest-0242\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\nest-0242\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\nest-0242\nest-02421\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\nest-0242\nest-02421\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\nest-0241\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\nest-0241\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-023\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-023\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-022\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-022\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-022\nest-0221\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-022\nest-0221\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-021\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-021\cross.dwg
F:\_kdub_testing\nest-0\nest-01\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-01\code .txt
F:\_kdub_testing\nest-0\nest-01\Copy nested stuff .txt
F:\_kdub_testing\nest-0\nest-01\cpuid.txt
F:\_kdub_testing\nest-0\nest-01\cross.dwg
F:\_kdub_testing\nest-0\nest-01\Shared Folder Test.txt
F:\_kdub_testing\nest-0\nest-01\nest-013\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-01\nest-013\cross.dwg
F:\_kdub_testing\nest-0\nest-01\nest-012\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-01\nest-012\cross.dwg
F:\_kdub_testing\nest-0\nest-01\nest-011\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-01\nest-011\cross.dwg
F:\_kdub_testing\Dwgs\SECT-HEAD-1R.dwg

 ----------- FindFilesRecursive(...  *.txt
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0341\squircle.txt
F:\_kdub_testing\nest-0\nest-01\code .txt
F:\_kdub_testing\nest-0\nest-01\Copy nested stuff .txt
F:\_kdub_testing\nest-0\nest-01\cpuid.txt
F:\_kdub_testing\nest-0\nest-01\Shared Folder Test.txt

 ----------- FindFilesRecursive(...  *nest*
F:\_kdub_testing\nest-0\nest-01\Copy nested stuff .txt

 ----------- FindFilesRecursive(...  Squircle.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0341\Squircle.dwg

 ----------- FindFilesRecursive(...  SQUIRCLE.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0341\Squircle.dwg


kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Findfile recursive ..
« Reply #1 on: December 19, 2008, 09:38:39 PM »
I 'spose I could try a LINQ Query as well ....  :|
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8695
  • AKA Daniel
Re: Findfile recursive ..
« Reply #2 on: December 19, 2008, 09:51:06 PM »
Nice work Kerry!  8-)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Findfile recursive ..
« Reply #3 on: December 19, 2008, 09:54:29 PM »

Thanks Dan.

Holidays are great .. plenty of research and play time :)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

TonyT

  • Guest
Re: Findfile recursive ..
« Reply #4 on: December 20, 2008, 11:52:38 PM »
FindFile in the net API is handy ... as it is in lisp ... but the limiting search folders is sometimes a restraint

... think of the case where you know the file you want is nested in a tree structure and because of dynamics you may not know the location.

This code is beta, but seems to do the job.


Assuming you actually wanted a non-recursive version,
I suppose that works.

Otherwise, this (which I've been using for ages) can do it:

Code: [Select]

/// Recursive file finder
///
///    E.g:  string files[] = FindFiles.Find( "d:\\MyDrawings", "*.dwg" );
///

public static class FindFiles
{
   public static string[] Find( string folder, string pattern )
   {
      List<string> result = new List<string>();
      Find( folder, pattern, result );
      return result.ToArray();
   }

   private static void Find( string folder, string pattern, List<string> result )
   {
      result.AddRange( Directory.GetFiles( folder, pattern ) );
      foreach( string directory in Directory.GetDirectories( folder ) )
         Find( Path.Combine( folder, directory ), pattern, result );
   }
}


It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8695
  • AKA Daniel
Re: Findfile recursive ..
« Reply #5 on: December 21, 2008, 12:08:34 AM »
Nice Tony!

I had heard a rumor that most code houses do not allow recursive functions in production code for fear of a stack overflow,
anyone know if this is true?  Obviously though, recursion is sometimes the most elegant way to solve certain tasks.  :mrgreen:

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Findfile recursive ..
« Reply #6 on: December 21, 2008, 12:12:22 AM »

Thanks Tony, I'll have a play tonight  ..

I assume the
///    E.g:  string files[] = FindFiles.Find( "d:\\MyDrawings", "*.dwg" );
should be
///    E.g:  string[] files = FindFiles.Find( "d:\\MyDrawings", "*.dwg" );


kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

TonyT

  • Guest
Re: Findfile recursive ..
« Reply #7 on: December 21, 2008, 02:55:42 AM »
Nice Tony!

I had heard a rumor that most code houses do not allow recursive functions in production code for fear of a stack overflow,
anyone know if this is true?  Obviously though, recursion is sometimes the most elegant way to solve certain tasks.  :mrgreen:


Hi Dan.

The decision is usually linked to praticle use, e.g., if you have a folder
structure deep enough to overflow the stack in a simple case like that,
you'd be better off firing the IT management that allowed things to get
that way, and give the programmer that wrote the recursive function
that merely exposed the larger problem a raise and a promotion :lmao:

I use recursion quite a bit, but in all cases I am more than confident
it will never go deep enough to use up the stack, and I have yet to
see it happen.

Also, there are quite a few compilers that know how to optimize
properly-tail-recursive code, and output iterative code that does
the job. I don't believe that C# does it, but most LISP and Scheme
compilers do, so an unconditional mandate banning recursion with
no regards to what tools are used or whether they can optimize
tail-recusive, seems a bit silly.

« Last Edit: December 21, 2008, 03:06:26 AM by TonyT »

uncoolperson

  • Guest
Re: Findfile recursive ..
« Reply #8 on: December 21, 2008, 12:11:08 PM »
I use this (sorry I'm way too lazy today to clean this up) for this thing http://www.theswamp.org/index.php?topic=10211.0

Quote
private bool refreshstuff(string thefoldername, TreeNode ParentNode)
        {
            bool keep = false;// used to keep track of keeping the node
            try
            {
                if (count <= maxfolder)// only do this until we hit max count, otherwise stop
                {
                    count++;
                    if (checkBox1.Checked)// subdirectories too?
                    {
                        string[] folderEntries = Directory.GetDirectories(thefoldername);// get the folders in 'thefoldername'
                        foreach (string curfolder in folderEntries) // for each folder process it recursivly (yay!)
                        {
                            TreeNode NextNode = ParentNode.Nodes.Add(curfolder);
                            if (!refreshstuff(curfolder, NextNode)) // see if refreshstuff says to keep things around
                            {
                                NextNode.Remove();
                                keep = keep | false;// i don't know why this is here... but i'm keeping it around anyway (shouldn't x | false == x)
                            }
                            else
                            {
                                keep = true; // we want to keep stuff because refreshstuff said so, so remember that
                            }
                        }
                    }

                }
*Giant file filtering snip (date of last edit, user that last edited, file name pattern)*
                else if (!err && checkBox1.Checked)// if we havenn't hit and error, and we do want to check subdirectories... but we have searched alittle too much let the user know
                {
                    MessageBox.Show(Form1.ActiveForm, "too many subfolders! get more detailed", "errr", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    err = true;// and keep track of this (don't want to be bombarded with errors
                }


*some more snipage*
            return keep;// let the calling function know what was found in the directory
        } // the thinking refresh tree function (recursive fun)
« Last Edit: December 21, 2008, 12:18:04 PM by uncoolperson »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Findfile recursive ..
« Reply #9 on: December 21, 2008, 10:00:46 PM »
and, because it's Monday and I'm home ....

a little LINQ

var InitialFolderList = new List<string> { @"F:\_kdub_testing"};
var dirQuery = InitialFolderList
   .Where(dir => Directory.Exists(dir))
   .SelectMany(dir =>
   Directory.GetFiles( dir, "*.*", SearchOption.AllDirectories) );
var filesQuery = InitialFolderList
   .Where(dir=> File.Exists(dir));
   
var SortedFileList = dirQuery.Union(filesQuery).OrderBy (s => s);

SortedFileList.Dump ("Ordered alphabetically");


Quote
F:\_kdub_testing\Dwgs\SECT-HEAD-1R.dwg
F:\_kdub_testing\nest-0\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\cross.dwg
F:\_kdub_testing\nest-0\nest-01\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-01\code .txt
F:\_kdub_testing\nest-0\nest-01\Copy nested stuff .txt
F:\_kdub_testing\nest-0\nest-01\cpuid.txt
F:\_kdub_testing\nest-0\nest-01\cross.dwg
F:\_kdub_testing\nest-0\nest-01\nest-011\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-01\nest-011\cross.dwg
F:\_kdub_testing\nest-0\nest-01\nest-012\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-01\nest-012\cross.dwg
F:\_kdub_testing\nest-0\nest-01\nest-013\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-01\nest-013\cross.dwg
F:\_kdub_testing\nest-0\nest-01\Shared Folder Test.txt
F:\_kdub_testing\nest-0\nest-02\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-021\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-021\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-022\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-022\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-022\nest-0221\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-022\nest-0221\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-023\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-023\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\nest-0241\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\nest-0241\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\nest-0242\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\nest-0242\cross.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\nest-0242\nest-02421\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-02\nest-024\nest-0242\nest-02421\cross.dwg
F:\_kdub_testing\nest-0\nest-03\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-031\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-031\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-032\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-032\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-032\nest-0321\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-032\nest-0321\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-032\nest-0322\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-032\nest-0322\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-033\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-033\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0341\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0341\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0341\Squircle.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0341\squircle.txt
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0342\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-034\nest-0342\cross.dwg
F:\_kdub_testing\nest-0\nest-03\nest-035\Alphabet Soup.dwg
F:\_kdub_testing\nest-0\nest-03\nest-035\cross.dwg
 
« Last Edit: December 21, 2008, 10:05:15 PM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8695
  • AKA Daniel
Re: Findfile recursive ..
« Reply #10 on: December 21, 2008, 10:03:31 PM »
Alphabet Soup.dwg  :laugh:

pkohut

  • Guest
Re: Findfile recursive ..
« Reply #11 on: December 21, 2008, 10:44:57 PM »
and, because it's Monday and I'm home ....

Monday? What UTM are you in?  10T for me.

Paul

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Findfile recursive ..
« Reply #12 on: December 21, 2008, 11:00:34 PM »
Gender:   yes
Age:         Mesozoic
Location:     Brisbane, Australia [ gmt +10 ]
Local Time: 2008-12-21, 14:00:45
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

pkohut

  • Guest
Re: Findfile recursive ..
« Reply #13 on: December 21, 2008, 11:12:46 PM »
Gender:   yes
Age:         Mesozoic
Location:     Brisbane, Australia [ gmt +10 ]
Local Time: 2008-12-21, 14:00:45

Ha, not ASL, but thanks.

Seattle, WA gmt-8
20:06:00, 12-21-08

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Findfile recursive ..
« Reply #14 on: December 21, 2008, 11:17:03 PM »
ok .. UTM is 56J
« Last Edit: December 21, 2008, 11:20:04 PM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.