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

时间:2009-07-23 21:37:01

标签: c# .net file file-io

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

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

在.NET中有一种简单的方法吗?是否有(#)构造的特殊名称?

8 个答案:

答案 0 :(得分:18)

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

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。无论如何,这就是我们为临时文件所做的事情。

答案 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;
}

答案 2 :(得分:3)

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

答案 3 :(得分: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或log(0).txt或log(1).txt或log(2).txt等

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

答案 4 :(得分:1)

对于LINQ-ish解决方案,请查看Keith Dahlby最近的博客文章“Improve Your Code Golf Game with LINQ”他非常优雅地涵盖了同样的问题。

答案 5 :(得分: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");

编辑:正如评论中指出的那样,这是一个带有重大错误的快速解决方案。

这是一个更慢(我想象)但更强大的解决方案:

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

答案 6 :(得分:0)

  • FileInfo extenion
  • 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);
        }
    }
    

答案 7 :(得分:0)

如果您一个接一个地执行一个文件,所有答案都很棒,但是如果您(或您的用户)正在上传文件并且您需要检查它是否存在并重命名新文件,请执行以下操作:< / p>

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

或类似的东西。