2009-07-23 9 views

Répondre

13

Vous devrez simplement compter et manipuler les noms de fichiers manuellement. Le code (pseudo) ci-dessous est sale, mais c'est l'algorithme de base. Refactoriser à vos besoins.

var filenameFormat = "FooBar{0}.xml"; 
var filename = string.Format(filenameFormat, ""); 
int i = 1; 
while(File.Exists(filename)) 
    filename = string.Format(filenameFormat, "(" + (i++) + ")"); 

return filename; 

Si vous pouvez vous en sortir, vous pouvez toujours coller sur DateTime.Now dans le format de votre choix. C'est ce que nous faisons pour les fichiers temporaires, de toute façon.

+0

+1 Me battre – Nifle

+1

Vous effectuez des appels répétés vers le système de fichiers. Obtenir les fichiers comme suggéré par person-b avec la méthode GetFiles peut être plus rapide pour un grand nombre de fichiers. –

+0

Serait-il plus préférable de dire 'filenameFormat =" FooBar ({0}). Xml ";' dans ce cas? – maxwellb

0

Je pense que vous auriez à faire quelque chose le long des lignes d'avoir un dictionnaire de noms de fichiers, comme ceci:

Dictionary<string, int> fileNameOccurences = new Dictionary<string, int>(); 
// ... 
string fileName = "FooBar"; 
if (fileNameOccurences.ContainsKey(fileName)) { 
    fileNameOccurences[fileName]++; 
    fileName += "(" + fileNameOccurences[fileName].ToString() + ")"; 
} 
else { fileNameOccurences.Add(fileName, 1); } 
SaveFile(fileName + ".xml"); 

Dans ce cas, vous devrez peut-être analyser l'extension ou refactor ou quelque chose comme cette.

Si vous ne disposez pas de contrôle sur les noms des fichiers dans le répertoire, vous pouvez compter les occurences manuellement:

string fileName = "FooBar"; 
string[] fileNames = Directory.GetFiles(theDirectory, fileName + "*.xml"); 
fileName += "(" + (fileNames.Count + 1).ToString() + ")"; 
SaveFile(fileName + ".xml"); 

EDIT: Comme cela a été souligné dans les commentaires, c'est une solution rapide et sale avec un bug majeur.

est ici plus lent (je pense), mais une solution plus robuste:

string fileName = "FooBar", directory = @"C:\Output"; 
int no = 0; 
while (++no > 0 && File.Exists(Path.Combine(directory, fileName + "(" + no.ToString() + ").xml"))); 
+0

Vous ignorer les numéros, si un fichier a été supprimé, ne sait pas si c'est la fonctionnalité prévue. –

+0

Ah. C'est un bug assez sérieux - s'ils avaient 1..5, supprimés 4, alors ils essaieraient d'écrire à # 5. –

2
/// <summary> 
/// Provides a filename given if it does not exist. 
/// If the filename exists, provides the lowest numeric number such that 
/// filename-number.ext does not exist. 
/// </summary> 
public static string GetNextFilename(string desiredFilename) 
{ 
    // using System.IO; 
    int num = 0; 
    FileInfo fi = new FileInfo(desiredFilename); 

    string basename = fi.FullName.Substring(0, fi.FullName.Length - fi.Extension.Length); 
    string extension = fi.Extension; 

    while(fi.Exists) 
    { 
     fi = new FileInfo(String.Format("{0}({1}){2}", 
      basename, 
      i++, 
      extension)); 
    } 

    return fi.FullName; // or fi.Name; 
} 

Ensuite, si vous avez une méthode qui permet d'économiser au fichier suivant: log.SaveTo(GetNextFileName(log.txt)); économisera à log.txt ou log (0) .txt ou log (1) .txt ou log (2) .txt, etc.

Si vous voulez pouvoir trier tous les fichiers par nom, utilisez un standard numeric format string dans le String.Format section.

2
string fileNameFormat = "FooBar{0}.xml"; 
string fileName = "FooBar.xml"; 
string filePath = "C:/"; 
string[] existingFiles = Directory.GetFiles(filePath, "FooBar*.xml"); 
int i = 1; 
while (existingFiles.Contains(filePath + fileName)) 
{ 
    fileName = string.Format(fileNameFormat, "(" + i + ")"); 
    i += 1; 
} 
5

En fin de compte, j'utilisé la réponse acceptée pour créer une méthode d'extension qui ressemble à ceci:

public static string GetNextFilename(this string filename) 
{ 
    int i = 1; 
    string dir = Path.GetDirectoryName(filename); 
    string file = Path.GetFileNameWithoutExtension(filename) + "{0}"; 
    string extension = Path.GetExtension(filename); 

    while (File.Exists(filename)) 
     filename = Path.Combine(dir, string.Format(file, "(" + i++ + ")") + extension); 

    return filename; 
} 
+0

ou peut-être 'string file = Path.GetFileNameWithoutExtension (nom de fichier) +" ({0}) ";' ' ' filename = Path.Combine (dir, string.Format (fichier, i ++) + extension); ' – DavidCC

0
  • FileInfo extenion
  • boucle au lieu de while et contre
  • énumérer les fichiers de répertoire en premier, moins fsio.

    public static class FileInfoExt 
    { 
        public static FileInfo DeDupue(this FileInfo f) 
        { 
         string path = f.FullName; 
    
         string directory = Path.GetDirectoryName(path); 
         string filename = Path.GetFileNameWithoutExtension(path); 
         string extension = Path.GetExtension(path); 
    
         string newFullPath = path; 
         IEnumerable<string> files = new DirectoryInfo(directory) 
          .EnumerateFiles().Select(r => r.FullName); 
    
         for (int i = 1; files.Contains(newFullPath); i++) 
         { 
          string newFilename = string.Format(
           "{0}({1}){2}", 
           filename, 
           i, 
           extension); 
          newFullPath = Path.Combine(directory, newFilename); 
         } 
    
         return new FileInfo(newFullPath); 
        } 
    } 
    
0

Toutes les réponses sont très bien si vous faites un fichier après l'autre, mais dire si vous (ou vos utilisateurs) téléchargez un fichier et que vous devez vérifier si elle existe et renommer le nouveau fichier faire quelque chose comme ceci:

string ExisitngFile = FIlePath+ FileNameWithTheExtension; 
      string[] splitTheFileName= FileNameWithTheExtension.Split('.'); 
      string extension = splitTheFileName[1]; 
      string name = splitTheFileName[0]; 
      int counter = 1; 
      while(File.Exists(FIlePath+ Path.GetFileName(name+" ("+counter +")" +"."+extension))) 
      { 
       counter ++; 

      } 
      string newFileName = name + " (" + li + ")" + "." + extension; 


      file.SaveAs(FIlePath+ Path.GetFileName(newFileName)); 

Ou quelque chose de similaire.

Questions connexes