2009-05-26 9 views
4

Je développe une application Windows dans VS2005 en utilisant C#. Dans mon projet, je génère des DLL et les stocke dans un répertoire. Les dll seront nommés TestAssembly1, TestAssembly2, TestAssembly3 etc.Comment stocker des valeurs persistantes de fichiers dans un répertoire?

Considérez donc si les trois DLLs ci-dessus se trouvent dans le répertoire. La prochaine fois que l'utilisateur utilise mon projet, j'ai besoin de générer des dlls comme TestAssembly4, TestAssembly5 etc.

Comment puis-je stocker le nombre de DLL dans le dossier et les incrémenter lorsque le projet est utilisé la prochaine fois?

Le répertoire peut même contenir des fichiers autres que dll. Alors, comment puis-je faire cela?

Répondre

10

Personnellement j'utiliser une recherche binaire pour trouver la prochaine assemblée. ..

  • start n = 1
  • ne TestAssembly1.dll existe? (oui)
  • TestAssembly2.dll existe-t-il? (oui)
  • est-ce que TestAssembly4.dll existe? (oui)
  • Est-ce que TestAssembly8.dll existe? (oui)
  • est-ce que TestAssembly16.dll existe? (oui)
  • est-ce que TestAssembly32.dll existe? (Pas)

et aucune utilisation recherche binaire entre 16 et 32:

  • -t TestAssembly24.dll existe? (oui)
  • est-ce que TestAssembly28.dll existe? (oui)
  • est-ce que TestAssembly30.dll existe? (non)
  • est-ce que TestAssembly29.dll existe? (Oui)

donc utiliser TestAssembly30.dll

Cela évite la nécessité de maintenir le compte séparément, donc ça va fonctionner même si vous supprimez tous les fichiers - et la recherche binaire signifie que vous n'avez pas avoir trop mauvaise performance.

Non testé, mais quelque chose comme ci-dessous; Notez également que quoi que ce soit basé sur l'existence de fichiers est immédiatement une condition de course (bien que généralement un très mince):

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

Cela dépend du domaine du problème. Avez-vous besoin d'une manipulation spéciale pour les lacunes? Est-ce que vous attendez seulement une poignée de fichiers à exister dans le répertoire dans des situations normales.(obtenir une liste complète de fichiers dans un répertoire est beaucoup moins cher que le même nombre d'opérations de fichier.exist) –

+0

@ sambo99 - "obtenir une liste complète .... est beaucoup moins cher"; cela dépend du nombre de fichiers dans le répertoire ... –

+0

@ sambo99; Notez qu'il n'y a que 6 tests file.Exists pour les 32 premiers fichiers. Cette approche ne vous oblige pas à obtenir une liste des fichiers du tout. –

1

Au lieu de beaucoup de vérifier si un fichier existe déjà, vous pouvez obtenir une liste de toutes les assemblées, extraire leur ID et retourner l'ID le plus élevé + 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; 
      } 
     } 
    } 
} 
Questions connexes