Я разрабатываю приложение Windows в VS2005 с использованием C #. В своем проекте я создаю библиотеки DLL и сохраняю их в каталоге. DLL будут называться TestAssembly1, TestAssembly2, TestAssembly3 и т. Д.

Так что подумайте, есть ли в каталоге три вышеуказанных DLL. В следующий раз, когда пользователь будет использовать мой проект, мне нужно будет сгенерировать библиотеки DLL, такие как TestAssembly4, TestAssembly5 и т. Д.

Итак, как я могу сохранить количество DLL в папке и увеличить их, когда проект будет использоваться в следующий раз?

Каталог может даже содержать файлы, отличные от dll. Так как я могу это сделать?

c#
6
SyncMaster 26 Май 2009 в 12:10

3 ответа

Лучший ответ

Вы бы просто использовали Directory.GetFiles, передав шаблон для файлов, которые хотите вернуть:

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

string[] files = Directory.GetFiles(@"C:\My Directory\", "TestAssembly*.dll");
4
samjudson 26 Май 2009 в 12:14

Лично я бы использовал двоичный поиск, чтобы найти следующую сборку ...

  • начало 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);
    }
12
Marc Gravell 26 Май 2009 в 12:36
Это зависит от проблемной области. Вам нужна специальная обработка зазоров? Ожидаете ли вы, что в обычных ситуациях в каталоге будет существовать лишь несколько файлов? (получение полного списка файлов в каталоге намного дешевле, чем такое же количество операций file.exist)
 – 
Sam Saffron
26 Май 2009 в 12:21
- «получить полный список .... намного дешевле»; это зависит от количества файлов в каталоге ...
 – 
Marc Gravell♦
26 Май 2009 в 12:34
@ sambo99; Обратите внимание, что файлов всего 6, существуют тесты для первых 32 файлов. Этот подход совсем не требует получения списка файлов.
 – 
Fredrik Mörk
26 Май 2009 в 12:37
Проверка наличия большого количества файлов дешевле, чем их перечисление?
 – 
VVS
26 Май 2009 в 12:42
- вы тестируете только часть файлов, которые могут существовать - так что вышеизложенное эффективно для плотных каталогов. Если у вас разреженный каталог, тогда хорошо: перечислите их все и найдите максимальное ...
 – 
Marc Gravell♦
26 Май 2009 в 12:45

Вместо того, чтобы постоянно проверять, существует ли уже файл, вы можете получить список всех сборок, извлечь их идентификаторы и вернуть наивысший идентификатор + 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;
            }
        }
    }
}
2
Sabuncu 22 Июл 2019 в 14:55