2009-07-23 2 views
3

Я вывод файлов в C# и хочу обрабатывать файлы сохраняются с тем же именем, добавляя скобки и ряд:Есть ли простой способ добавить (#) к имени файла, когда вы найдете дубликат имени файла?

FooBar.xml 
FooBar(1).xml 
FooBar(2).xml 
... 
FooBar(N).xml 

есть простой способ сделать это в .NET? И есть ли специальное название для конструкции (#)?

ответ

13

Вам просто нужно будет вручную подсчитывать и изменять имена файлов. Ниже (псевдо) код грязный, но это основной алгоритм. Рефакторинг его в соответствии с вашими потребностями.

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

return filename; 

Если вы можете уйти с ним, вы всегда можете просто лавировать на DateTime.Now в формате вашего выбора. В любом случае, это то, что мы делаем для временных файлов.

+0

+1 Beat me to it – Nifle

+1

Вы делаете повторные вызовы в файловую систему, получение файлов, как было предложено человеком-b, с помощью метода GetFiles может быть быстрее для большого количества файлов. –

+0

Было бы предпочтительнее сказать 'filenameFormat =" FooBar ({0}). Xml ";' в этом случае? – maxwellb

0

Я думаю, что вы должны сделать что-то вдоль линий, имеющих словарь имен файлов, например:

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

В этом случае, возможно, потребуется разобрать расширение или рефакторинг или что-то вроде что.

Если вы не имеете контроля над именами файлов в каталоге, то вы можете рассчитывать вхождений вручную:

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

EDIT: Как было отмечено в комментариях, это быстрое и грязное решение с большой ошибкой.

Вот медленнее (я полагаю,), но более надежное решение:

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

Вы бы пропустили числа, если файл был удален, не уверен, что это назначенная функциональность. –

+0

Ах. Это довольно серьезная ошибка - если они имели 1..5, удалили 4, то попытались бы написать №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; 
} 

Тогда, если у вас есть метод, который сохраняет к следующему файлу: log.SaveTo(GetNextFileName(log.txt)); сохранит в log.txt или войти (0) .txt или log (1) .txt или log (2) .txt и т. Д.

Если вы хотите иметь возможность сортировать все файлы по имени все время, используйте standard numeric format string в String.Format раздел.

1

Для решения LINQ-ish, посмотрите последнее сообщение в блоге Кейта Далби, «Improve Your Code Golf Game with LINQ» Он довольно элегантно освещает этот вопрос.

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

В конце концов я использовал принятый ответ, чтобы создать метод расширения, который выглядит следующим образом:

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

или, возможно, 'string file = Path.GetFileNameWithoutExtension (filename) +" ({0}) ";' 'filename = Path.Combine (dir, string.Format (файл, i ++) + расширение);' – DavidCC

0
  • FileInfo extenion
  • цикл вместо в то время как петли и счетчик
  • сначала перечислите файлы каталогов, меньше 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

Все ответы являются большими, если вы делаете один файл за другим, но говорят, что если вы (или ваши пользователи) загружаете файл, и вы должны проверить, если он существует, и переименовывать новый файл сделать примерно так:

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

Или что-то подобное.

Смежные вопросы