代码之家  ›  专栏  ›  技术社区  ›  Gavin Miller

当您找到重复的文件名时,是否有一种简单的方法可以将()添加到文件名中?

  •  4
  • Gavin Miller  · 技术社区  · 16 年前

    我在C中输出文件,并希望通过添加括号和数字来处理以相同名称保存的文件:

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

    在.NET中有一个简单的方法可以做到这一点吗?有没有特别的名字 (#) 构造?

    8 回复  |  直到 16 年前
        1
  •  17
  •   Samantha Branham    16 年前

    您只需要手动计算和操作文件名。下面的(伪)代码是脏的,但它是基本算法。根据需要重构它。

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

    如果你能摆脱它,你可以一直在日期时间上。现在以你选择的格式。不管怎样,这就是我们处理临时文件的方法。

        2
  •  5
  •   Gavin Miller    16 年前

    最后,我使用接受的答案创建了一个如下所示的扩展方法:

    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;
    }
    
        3
  •  3
  •   Yuriy Faktorovich    16 年前
    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;
    }
    
        4
  •  2
  •   maxwellb    16 年前
    /// <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或log(0).txt或log(1).txt或log(2).txt等。

    如果希望能够始终按名称对所有文件进行排序,请使用 standard numeric format string 在string.format部分。

        5
  •  1
  •   David Alpert    16 年前

    要想找到解决这个问题的方法,请查看KeithDahlby最近的博客文章。” Improve Your Code Golf Game with LINQ “他对同一个问题的论述非常优雅。

        6
  •  0
  •   Lucas Jones    16 年前

    我想你得做点什么,比如说,你必须有一本文件名词典:

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

    编辑 :正如评论中指出的,这是一个快速而肮脏的解决方案,有一个主要的错误。

    这里有一个更慢(我想)但更健壮的解决方案:

    string fileName = "FooBar", directory = @"C:\Output";
    int no = 0;
    while ( ++no > 0 && File.Exists(Path.Combine(directory, fileName + "(" + no.ToString() + ").xml")) );
    
        7
  •  0
  •   Matt    11 年前
    • 文件信息扩展
    • for循环而不是while循环和计数器
    • 先枚举目录文件,不要使用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);
          }
      }
      
        8
  •  0
  •   Иво Недев    10 年前

    如果你一个接一个地做一个文件,所有的答案都很好,但是如果你(或你的用户)正在上传一个文件,你需要检查它是否存在,然后重命名新文件,这样做:

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

    或者类似的东西。