1

I need to get a list of all files on a handheld device whose names fit a certain pattern, such as "ABC.XML"

I adapted code from here (Hernaldo's answer), like so:

public static List<string> GetXMLFiles(string fileType, string dir)
{
    string dirName = dir; // call it like so: GetXMLFiles("ABC", "\\");  <= I think the double-whack is what I need for Windows CE device...am I right?
    var fileNames = new List<String>();
    try
    {
        foreach (string f in Directory.GetFiles(dirName))
        {
            if ((f.Contains(fileType)) &&  (f.Contains(".XML")))
            {
                fileNames.Add(f);
            }
        }
        foreach (string d in Directory.GetDirectories(dirName))
        {
            GetXMLFiles(fileType, d);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    return fileNames;
}

...but each time the method recursively calls itself (in the GetDirectories() loop), I'm passing the same old first arg. Is it possible (in Compact Framework) to do something like this instead:

public static List<string> GetXMLFiles(optional string fileType, string dir)
{
        . . .        
        foreach (string d in Directory.GetDirectories(dirName))
        {
            GetXMLFiles(dir = d);
        }
        . . .

?

UPDATE

According to Habib, this should work (new "try" section):

try
{
    string filePattern = string.Format("*{0}*.XML", fileType);
    foreach (string f in Directory.GetFiles(dirName, filePattern))
    {
        fileNames.Add(f);
    }
    foreach (string d in Directory.GetDirectories(dirName))
    {
        GetXMLFiles(fileType, d);
    }
}

Ja?

UPDATE 2

This goes along with my second response to Alan's comment below:

const string EXTENSION = ".XML";
. . .
try
{
    foreach (string f in Directory.GetFiles(dirName))
    {
        string ext = Path.GetExtension(f);
        string fileNameOnly = Path.GetFileNameWithoutExtension(f);
        if ((ext.Equals(EXTENSION, StringComparison.Ordinal)) && (fileNameOnly.Contains(fileType)))
        {
            fileNames.Add(f);
        }
    }
    foreach (string d in Directory.GetDirectories(dirName))
    {
        GetXMLFiles(fileType, d);
    }
}
Community
  • 1
  • 1
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • 1
    That code does look a little shady.. I would look into using the defined Path.GetExtension method to get the extension and compare it to .xml with StringComparison.OrdinalIgnoreCase. Then also Path.GetFilenameWithoutExtension to search the other part of the file for ABC (or similar depending on your requirements) – Alan Mar 04 '14 at 18:00
  • Are all these fineries available for the CompactFramework subset? – B. Clay Shannon-B. Crow Raven Mar 04 '14 at 18:02
  • So are you saying that my Update2 is better than Update (1), or just how should that be implemented, and why would it be better? – B. Clay Shannon-B. Crow Raven Mar 04 '14 at 18:17
  • 1
    It's better, but the method still looks like it needs work. I don't see you returning any file names from GetXMLFiles? Also, you need OrdinalIgnoreCase not Ordinal, assuming you want it to be case insensitive. Using the built in Path methods are much less prone to error than your own method. What if the file name is SomeShadyFile.XML.exe ? – Alan Mar 04 '14 at 18:56
  • Intellisenseless is partially to blame for the Ordinal/OrdinalIgnoreCase; I had intended the latter, and somehow got the former. Okay, it's my fault: I wasn't paying enough attention. I do return the vals ("return fileNames;") – B. Clay Shannon-B. Crow Raven Mar 04 '14 at 19:02
  • 1
    That's interesting, but are you adding the returned filenames to the list from the previous recursive call? (It isn't in there). You may also want to look into returning an IEnumerable with a yield return statement (which may allow you to avoid keeping that list around altogether) – Alan Mar 04 '14 at 19:14
  • Is yield available in the CompactFramework .NET subset? – B. Clay Shannon-B. Crow Raven Mar 04 '14 at 19:23
  • I don't understand your concern - the files are being added to the List in the initial foreach loop - each time it is hit, for every directory, and at the end -- after all directories and their files have been exhaustively searched -- the generic List of string is returned. – B. Clay Shannon-B. Crow Raven Mar 04 '14 at 19:28
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/48993/discussion-between-alan-and-b-clay-shannon) – Alan Mar 04 '14 at 19:45

2 Answers2

2

Optional parameters are a feature of .NET 4.0, so you won't be able to use them. The typical solution to this with a recursive function is to create two overloads for your method with different parameters.

For example,

BinarySearch(array a);
{
  BinarySearch(a, -1, array.Length);
} 

BinarySearch(array, low, high)
{
   //code to update low high
   return BinarySearch(array, low, high);
}

In this case, the method which kicks off the recursion has a slightly different signature. You could do the same.

Alan
  • 7,875
  • 1
  • 28
  • 48
1

Directory.GetFiles has an overload which takes search pattern you can use that:

Directory.GetFiles(dirName, "ABC.XML")

You can also use wildcards like "*.XML" which would return all XML files.

Habib
  • 219,104
  • 29
  • 407
  • 436
  • At any rate, that's great info (thanks!), but it doesn't answer the question. – B. Clay Shannon-B. Crow Raven Mar 04 '14 at 17:15
  • 1
    @B.ClayShannon, I completely misunderstood the question, You are looking for default parameter with a method, they are available with C# 4.0. You can create multiple overloaded methods one with the parameter and the other without. – Habib Mar 04 '14 at 17:44