如何在目录中持久保存文件的值?

时间:2009-05-26 08:10:08

标签: c#

我正在使用C#在VS2005中开发Windows应用程序。在我的项目中,我生成dll并将它们存储在一个目录中。 dll将命名为TestAssembly1,TestAssembly2,TestAssembly3等。

因此,请考虑以上三个dll是否在目录中。下次用户使用我的项目时,我需要生成像TestAssembly4,TestAssembly5等dll。

那么如何在文件夹中存储dll的数量并在下次使用项目时增加它们?

该目录甚至可以包含dll以外的文件。那我怎么能这样做呢?

3 个答案:

答案 0 :(得分:11)

就个人而言,我会使用二进制搜索来查找下一个程序集......

  • start n = 1
  • TestAssembly1.dll存在吗? (是)
  • TestAssembly2.dll存在吗? (是)
  • TestAssembly4.dll存在吗? (是)
  • TestAssembly8.dll存在吗? (是)
  • TestAssembly16.dll存在吗? (是)
  • TestAssembly32.dll存在吗? (无)

并且不使用16和32之间的二进制搜索:

  • TestAssembly24.dll存在吗? (是)
  • TestAssembly28.dll存在吗? (是)
  • TestAssembly30.dll存在吗? (无)
  • TestAssembly29.dll存在吗? (是)

所以使用TestAssembly30.dll

这样就无需单独保存计数,因此即使删除所有文件也能正常工作 - 二进制搜索意味着您的性能不会太差。

未经测试,但如下所示;另请注意,基于文件存在的任何会立即成为竞争条件(尽管通常非常小):

    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);
    }

答案 1 :(得分:4)

您只需使用Directory.GetFiles,传入要返回的文件的模式:

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

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

答案 2 :(得分:1)

您可以获取所有程序集的列表,提取其ID并返回最高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 ExtractIdsFromAssemblyList(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;
            }
        }
    }
}