You want to list every subdirectory and file within a directory. | Technique Using the GetDirectories and GetFiles methods is fine if you want to get the directory and filenames that are direct descendants of a directory. However, sometimes you might want to get all the descendants. To do so, you can employ a common programming technique known as recursion . In the next code listing, the Enumerate method enumerates each FileSystemInfo object within a certain directory. If the FileSystemInfo is a DirectoryInfo type, then the method calls itself passing in the new starting location: private void Enumerate( DirectoryInfo diStart, int indent ) { try { // for each subdirectory and file foreach (FileSystemInfo diNext in diStart.GetFileSystemInfos()) { // indent the output for( int i = 0; i < indent; ++i ) { swLogFile.Write( "\t" ); } // check if object is a subdirectory if( diNext.GetType() == typeof( DirectoryInfo )) { // write out subdirectory name surrounded by brackets swLogFile.WriteLine( "< " + diNext.Name + ">"); // recursive function call with new starting location Enumerate( (DirectoryInfo) diNext, ++indent ); } else { // write out name of file swLogFile.WriteLine( diNext.Name ); } } } catch (Exception e) { Console.WriteLine("The process failed: {0}", e.ToString()); } } Comments The preceding code might take a while to run if you point the starting location to the root folder of a large hard drive. The indenting was placed in the file for readability purposes, but it also demonstrates how the runtime stack is used within the Common Language Runtime (CLR). Without knowing anything about recursion or call stacks, one might assume that each time the indent parameter is incremented, the output just keeps indenting and never reverts back to a lower value. Whenever parameters are used within a method, they are placed on the stack by the caller. Therefore, when you see the Enumerate method call itself in response to finding a new subdirectory, the new subdirectory contained within the DirectoryInfo object and a new incremented indent value is placed onto the call stack and the call is made. When the second Enumerate method returns, the old indent value is restored because value types are popped off the stack when the callee begins execution. However, if the parameter being passed in was by reference, then the new value would remain and the indentation would be incorrect. If you have run into recursion before, then the procedure more than likely isn't anything new to you. If you have never seen recursive procedures before, then don't feel bad if you don't understand it conceptually. |