C# 如何在目录中持久存储文件的值?

C# 如何在目录中持久存储文件的值?,c#,C#,我正在使用C#在VS2005中开发一个Windows应用程序。在我的项目中,我生成DLL并将它们存储在一个目录中。DLL将命名为TestAssembly1、TestAssembly2、TestAssembly3等 请考虑上述三个DLL是否在目录中。下次用户使用我的项目时,我需要生成DLL,如TestAssembly4、TestAssembly5等 那么,如何将DLL的计数存储在文件夹中,并在下次使用项目时增加它们 该目录甚至可以包含DLL以外的文件。那么我该怎么做呢?您只需使用Directory

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

请考虑上述三个DLL是否在目录中。下次用户使用我的项目时,我需要生成DLL,如TestAssembly4、TestAssembly5等

那么,如何将DLL的计数存储在文件夹中,并在下次使用项目时增加它们


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

您只需使用Directory.GetFiles,为要返回的文件传递一个模式:


我个人会使用二进制搜索来查找下一个程序集

  • 开始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

这避免了单独保存计数的需要,因此即使删除了所有文件,它也可以工作,而二进制搜索意味着您的性能不会太差

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


您可以获取所有程序集的列表,提取它们的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 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;
            }
        }
    }
}
int-nextId=GetNextIdFromFileNames(
“组装路径”,
“TestAssembly*.dll”,
@“TestAssembly(\d+\.dll”);
[...]
public int GetNextIdFromFileNames(字符串路径、字符串文件模式、字符串regexpatern)
{
//获取所有文件名
string[]files=Directory.GetFiles(路径、文件模式、SearchOption.TopDirectoryOnly);
//从每个文件中提取ID,获取最高ID并返回+1
返回ExtractIdsFromFileList(文件,regexpatern)
.Max()+1;
}
私有IEnumerable ExtractIdsFromFileList(字符串[]文件,字符串regexpatern)
{
Regex Regex=new Regex(regexpatern,RegexOptions.IgnoreCase);
foreach(文件中的字符串文件)
{
Match=regex.Match(文件);
如果(匹配成功)
{
int值;
if(int.TryParse(match.Groups[1].Value,out Value))
{
收益回报值;
}
}
}
}

这取决于问题域。是否需要对间隙进行特殊处理?您是否希望在正常情况下目录中只存在少数文件。(在目录中获取完整的文件列表要比相同数量的file.exist操作便宜得多)@sambo99-“获取完整列表……要便宜得多”;这取决于目录中的文件数…@sambo99;请注意,前32个文件只有6个file.Exists测试。这种方法根本不需要您获取文件列表。测试大量文件是否存在比枚举大量文件便宜?@David-您只测试可能存在的部分文件-因此上述方法对于密集目录是有效的。如果您有一个稀疏目录,那么很好:列出所有目录并找到最大值。。。
    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);
    }
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;
            }
        }
    }
}