How to store values persistenly of files in a directory?

Personally I'd use a binary search to find the next assembly...

  • start n=1
  • does TestAssembly1.dll exist? (yes)
  • does TestAssembly2.dll exist? (yes)
  • does TestAssembly4.dll exist? (yes)
  • does TestAssembly8.dll exist? (yes)
  • does TestAssembly16.dll exist? (yes)
  • does TestAssembly32.dll exist? (no)

and no use binary search between 16 and 32:

  • does TestAssembly24.dll exist? (yes)
  • does TestAssembly28.dll exist? (yes)
  • does TestAssembly30.dll exist? (no)
  • does TestAssembly29.dll exist? (yes)

so use TestAssembly30.dll

This avoids the need to keep the count separately, so it'll work even if you delete all the files - and the binary search means you don't have too bad performance.

Untested, but something like below; also note that anything based on file existence is immediately a race condition (although usually a very slim one):

    static string GetNextFilename(string pattern) {
        string tmp = string.Format(pattern, 1);
        if (tmp == pattern) {
            throw new ArgumentException(
                 "The pattern must include an index place-holder", "pattern");
        }
        if (!File.Exists(tmp)) return tmp; // short-circuit if no matches

        int min = 1, max = 2; // min is inclusive, max is exclusive/untested
        while (File.Exists(string.Format(pattern, max))) {
            min = max;
            max *= 2;
        }

        while (max != min + 1) {
            int pivot = (max + min) / 2;
            if (File.Exists(string.Format(pattern, pivot))) {
                min = pivot;
            }
            else {
                max = pivot;
            }
        }
        return string.Format(pattern, max);
    }

You would just use Directory.GetFiles, passing in a pattern for the files you want to return:

http://msdn.microsoft.com/en-us/library/wz42302f.aspx

string[] files = Directory.GetFiles(@"C:\My Directory\", "TestAssembly*.dll");

Instead of lots of checking if a file already exist you can get a list of all assemblies, extract their ID's and return the highest ID + 1:

int nextId = GetNextIdFromFileNames(
               "pathToAssemblies", 
               "TestAssembly*.dll", 
               @"TestAssembly(\d+)\.dll");

[...]

public int GetNextIdFromFileNames(string path, string filePattern, string regexPattern)
{
    // get all the file names
    string[] files = Directory.GetFiles(path, filePattern, SearchOption.TopDirectoryOnly);

    // extract the ID from every file, get the highest ID and return it + 1
    return ExtractIdsFromFileList(files, regexPattern)
           .Max() + 1;
}

private IEnumerable<int> ExtractIdsFromFileList(string[] files, string regexPattern)
{
    Regex regex = new Regex(regexPattern, RegexOptions.IgnoreCase);

    foreach (string file in files)
    {
        Match match = regex.Match(file);
        if (match.Success)
        {
            int value;
            if (int.TryParse(match.Groups[1].Value, out value))
            {
                yield return value;
            }
        }
    }
}

Tags:

C#