Recursive search examples, pt1: C#
In light of my recent article on recls 100% .NET, I thought I'd do some bits on the recls library: the C/C++ version, and the new .NET version.
First up, let's write a utility that, say, reports the number of C# source files in/under the current directory, excluding the ubiquitous Properties/AssemblyInfo.cs, and reports on the total size of all. We'll write it in C# using recls 100%.NET and in C & C++ using recls. As you'll see, we see a pretty obvious difference in development effort, which probably isn't a surprise. What is a surprise, given the application domain, is there's a substantial performance difference, which I think might be due to the .NET runtime.
Here's the first version of the code:
<br />namespace CSharpSourceFinder <br />{ <br /> using Recls; <br /> <br /> using System; <br /> <br /> class Program <br /> { <br /> static void Main(string[] args) <br /> { <br /> int numFiles = 0; <br /> long totalSize = 0; <br /> <br /> foreach(IEntry entry in FileSearcher.Search(null, "*.cs")) <br /> { <br /> if(0 == String.Compare("AssemblyInfo.cs", entry.File, StringComparison.CurrentCultureIgnoreCase)) <br /> { <br /> if(0 == String.Compare(@"Properties\f", entry.DirectoryParts[entry.DirectoryParts.Count - 1], StringComparison.CurrentCultureIgnoreCase)) <br /> { <br /> continue; <br /> } <br /> } <br /> <br /> ++numFiles; <br /> totalSize += entry.Size; <br /> } <br /> <br /> Console.Out.WriteLine("{0} file(s); {1} bytes", numFiles, totalSize); <br /> } <br /> } <br />} This looks good. Unfortunately, when I ran it on in the root directory of my work drive, I (eventually) ended up with a System.UnauthorizedAccessException, thrown when an inaccessible (but non-hidden, non-system) directory was encountered. Now, the directory was created several months ago to test this very behaviour in recls, but that doesn't mean it should not be handled appropriately. To handle this, we need to make a change:
<br />. . . <br /> foreach(IEntry entry in FileSearcher.Search(null, "*.cs"<strong>, SearchOptions.IgnoreInaccessibleNodes</strong>)) <br />. . .
This now succeeds, and the output (run via a utility that measures process time characteristics) is:
1354 file(s); 6540661 bytes
time: elapsed: 20593ms, kernel: 11796ms, user: 8640ms
This took me less than 10 minutes to write. In the next post, I'll look at the C equivalent.

