Ohad's Blog

Lets talk about .net !

Mirror at:
blogs.microsoft.co.il

News

         Ohad Israeli's Facebook profile

Grab this badge here!

C# Code Snippts

Favorite Blogs

Israeli .Net Bloggers

How to loop through all files in a folder using C#

Someone asked me how to loop through all the files in a folder...
well just a quick sample recursive solution...

Update: Thanks to Avner's comment I've noticed that the original code I've posted here was vulnerable to File System Reparse Point issue.

What is File System Reparse Point issue ?
When compiling the code and running if you add a reparse point to (c:\temp\recursive1\recursive2 -> c:\temp\recursive1). After a few recursions you get “System.IO.IOException: The name of the file cannot be resolved by the system.”. At the time of failure it was looking for c:\temp\recursive1\recursive2\recursive2\recursive2\recursive2\recursive2\recursive2\recursive2\recursive2\rerecursive2\recursive2\recursive2

MS Press Writing Secure Code 2
pages 686-7 includes the following information regarding File System Reparse Point Issues:
 
"Starting in windows 2000 NFTS supports directory junctions. This is similar to a UNIX symbolic link that redirects a reference from one directory to another directory on the same machine. You can create and manage directory junctions using Linkd.exe a tool available in the Windows Resource Kit."

"Directory junctions present a threat to any application that does a recursive traversal of the directory structure."

"It is the responsibility of any application that scans the directory hierarchy and especially the responsibility of applications that make destructive changes recursively through the directory hierarchy to recognize directory junctions and avoid traversing through them, Because directory junctions are implementer using reparse points, applications should see if a directory has the FILE_REPARSE_POINT attribute set before processing that directory. Your code is safe if you do not process any directory with FILE_REPARSE_POINT set which you can verify with functions such as GetFileAttributes and lpFindFileData->dwFileAttributes in FindFirstFile."

While looking for a gui tool to create Symbolic files I've found Winbolic Link which can create NTFS Junction and Shell Links
The program 
creates these links using only built-in functionality of Windows. It does not extend or modify the functionality of Windows or the file system, or require any service to remain running to maintain functionality. It merely creates the special kinds of files and folders Windows already supports, but which Microsoft did not distribute tools to create.

You can see that now I've implemented the check for ReparsePoint and my code is safe again :-)

Ohad.

// How much deep to scan. (of course you can also pass it to the method)
const int HowDeepToScan=4;

public
static void ProcessDir(string sourceDir, int recursionLvl) 
{
  if (recursionLvl<=HowDeepToScan)
  {
    // Process the list of files found in the directory.
    string [] fileEntries = Directory.GetFiles(sourceDir);
    foreach(string fileName in fileEntries)
    {
       // do something with fileName
       Console.WriteLine(fileName);
    }

    // Recurse into subdirectories of this directory.
    string [] subdirEntries = Directory.GetDirectories(sourceDir);
    foreach(string subdir in subdirEntries)
       // Do not iterate through reparse points
       if ((File.GetAttributes(subdir) &
           
 FileAttributes.ReparsePoint) !=
                FileAttributes.ReparsePoint)

            ProcessDir(subdir,recursionLvl+1);
  }

}

Posted: Jun 23 2004, 12:32 AM by Ohad Israeli | with 20 comment(s)
Filed under:

Comments

Roy Osherove said:

Am I wrong or are you not paying any attention to the recursionLvl parameter in your code?
# June 22, 2004 6:34 PM

Ohad Israeli said:

You are not wrong... you can control how many levels deep to scan... i just haven't implemented it....
# June 23, 2004 1:50 AM

Avner Kashtan said:

One small problem that can arise here - starting with Windows 2000, NTFS allows you to have symbolic links and remount points in your filesystem. This means that my C:\Folder\Beep can actually be C:\ mounted under a different name - and possibly go into an endless loop if you don't specify a maximum depth. Working around this is a headache - to find out whether a folder is actually a remount point, you have to P/Invoke and get nasty.
# June 23, 2004 1:06 PM

Ohad Israeli said:

Thats correct... there was a prob. and now its gone,
I just fixed the code and... didn't have to use P/Invoke

:-)
# June 23, 2004 4:47 PM

Avner Kashtan said:

Cool, I didn't know you could access the IsReparsePoint property from managed code.
I haven't been in a position to write filesystem-intensive code lately, so I never really got to use the full range of System.IO classes. In my mind, I'm still doing it with VBScript and the FileSystemObject. :)
# June 24, 2004 1:46 AM

Lolita said:

I getting errors, that filename, file and directory doesnot exist in current context, how to fix it?
# June 16, 2006 8:07 AM

Stephen’s Personal Blog » Blog Archive » Recursively Iterate Through Folders Using c# said:

Pingback from  Stephen&#8217;s Personal Blog  &raquo; Blog Archive   &raquo; Recursively Iterate Through Folders Using c#

# August 14, 2007 9:21 PM

Stephen’s Personal Blog » Blog Archive » Flickr App to Upload Organized Files said:

Pingback from  Stephen&#8217;s Personal Blog  &raquo; Blog Archive   &raquo; Flickr App to Upload Organized Files

# August 14, 2007 10:53 PM

Martin Svendsen said:

Hi,

Here is another way to get filenames from all files, including subdirectories (notice the SearchOption.AllDirectories parametre):

// Process the list of files found in all directory.

string [] fileEntries = Directory.GetFiles(sourceDir, "*", SearchOption.AllDirectories);

foreach(string fileName in fileEntries)

{

  // do something with fileName

  Console.WriteLine(fileName);

}

If you change the "*" to ex. "*.log" you will get all filenames that ends with ".log".

# February 20, 2008 4:43 AM

B V Ramana said:

I have different folders with different files.how i can i read all files in to dataset.once if i read files i will not use folders path.please help me

# April 10, 2008 5:57 AM

Roozbeh said:

What do I need to include for this code to fly?

# June 19, 2008 8:19 PM

How to loop through all files in a folder using C# « for developer said:

Pingback from  How to loop through all files in a folder using C# &laquo; for developer

# June 25, 2008 3:40 AM

varun said:

Thanks that was really helpful for me

# September 11, 2008 3:48 PM

Fes said:

Hi, thanks for this code it worked really well.

# October 24, 2008 11:34 AM

Hitesh said:

Good and Helpful article.

# November 22, 2008 2:38 AM

a said:

       private void SearchStuff(string Directory, string search)

       {

           DirectoryInfo test = new DirectoryInfo(Directory);

           DirectoryInfo[] sub = test.GetDirectories("*"+search+"*",SearchOption.AllDirectories);

           FileInfo[] sub2 = test.GetFiles("*" + search + "*", SearchOption.AllDirectories);

           int count = sub.Length + sub2.Length;

           ttlCount += sub.Length + sub2.Length;

           int a = 0;

           if (count > 0)

           {

               ListViewItem[] temp = new ListViewItem[count];

               for (int i = 0; i < sub.Length; i++)

               {

                   temp[i] = new ListViewItem(new string[] { sub[i].Name, sub[i].FullName });

               }

               for (int i = sub.Length; i < count; i++)

               {

                   temp[i] = new ListViewItem(new string[] { sub2[a].Name, sub2[a].FullName });

                   a++;

               }

               listView1.Items.AddRange(temp);

           }

# November 28, 2008 5:12 PM

Sujit said:

hi

i want to access a folder in other system that is shared and check for files in that folder greater than 1mb and return the count using C# ... can any1 help??

# February 20, 2009 5:07 AM

Skot said:

Hi there

I wonder whether you are over-complicating matters by wondering about maximum scan depth, etc.

There's a much easier way to iterate through folders to any depth, which I discuss in my blog at skotl.blogspot.com/.../iterating-through-bunch-of-folders-and.html

Regards

 Scott

# July 11, 2009 9:19 PM

Rober Brown said:

Thanks for the post. Really helpful.  Makes me look like a genius

# July 22, 2009 11:48 AM

Eravse said:

hi i wrote a simple convertor tool from file server to web server in the local network .

this code match file server folder and web server folder and than remove similar name and add two list boxes .

i hope this code help every one .

regards

       public void getFiles(string path)

       {  int total_item_file_server=0;

           string[] fileEntries = Directory.GetFiles(path);

           foreach (string fileName in fileEntries)

           {

               patinent_images_server.Items.Add(fileName.Replace("j:\\images\\patinet\\","").Replace(".bmp",""));

               total_item_file_server++;

           }

           label3.Text += " total Item: " + total_item_file_server;

       }

       private void Form1_Load(object sender, EventArgs e)

       {

           getFiles("j:\\images\\patient\\");

           string[] fileEntries = Directory.GetFiles("R:\\");

           int total_item_web_server = 0;

           foreach (string fileName in fileEntries)

           {

               patient_images_web.Items.Add(fileName.Replace("R:\\","").Replace(".jpg",""));

               total_item_web_server++;

           }

           int removeitem=0;

         /* if u wanna match list boxes and if folder have a images remove  from to listbox

           foreach (object i in patinet_images_web.Items)

           {

               if (patient_images_web.Items.Contains(i))

               {

                   patient_images_server.Items.Remove(i);

                   removeitem++;

               }

           }

*/

           label3.Text += " Removed : " + removeitem;

           label4.Text += " Total Item : " + total_item_web_server;

       }

       private void button3_Click(object sender, EventArgs e)

       {

           progressBar1.Minimum = 0;

           progressBar1.Maximum = patient_images_server.Items.Count;

           for (int i = 0; i < patient_images_server.Items.Count; i++)

           {

               textBox2.Text = "";

               if (progressBar1.Value == patient_images_server.Items.Count)

               {

                   MessageBox.Show("Convert complate");

               }

                   string image_path = "j:\\images\\patient\\" + patient_images_server.Items[i] + ".bmp";

                   Image img = Image.FromFile(image_path.Replace(".BMP",""));

                   img.Save("R:\\" + i + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

                   textBox2.Text = "R:\\" + i + ".jpg";

                   progressBar1.Value++;

                   System.Threading.Thread.Sleep(50);

                   System.GC.Collect();

                   img.Dispose();

           }

       }

# November 2, 2009 7:05 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)