FileUpload - 如果文件名存在,则在名称末尾的括号之间连接一个数字

时间:2017-07-31 12:33:06

标签: c# asp.net file-upload

我想将文件(一次一个)上传到文件夹:

GetUniqueName函数(如下所述)将返回唯一的文件名

这是我用来做的代码:

public static string GetUniqueName(string fileName)
{
        string dir = Globals.Directories.GetCustomCategoryThumbnailDir();
        string fileExtension = Path.GetExtension(fileName);
        string fileNameWE = Path.GetFileNameWithoutExtension(fileName);
        string[] files = Directory.GetFiles(dir, "*" + fileExtension)
                                .Select(Path.GetFileName)
                                .ToArray();
        string uniqueName = fileNameWE;
        int nextNum = 0;
        bool fileExist = false;
        string pattern = @"(.*)\(([\d]+)\)";

        foreach (var file in files)
        {
            var tempFileName = Path.GetFileNameWithoutExtension(file);
            var match = Regex.Match(tempFileName, pattern);

            if (tempFileName.Equals(fileNameWE))
            {
                // file exist in folder
                fileExist = true;
            }
            if (tempFileName.StartsWith(fileNameWE) && match.Success)
            {
                // there is a file name that start with "fileToUpload" name, we want to to take the number
                nextNum = Convert.ToInt32(match.Groups[2].Value);
                nextNum++;
            }
        }

        if (nextNum == 0 && !fileExist)
        {
            // filename dont exist                
            return fileNameWE + fileExtension;
        }
        if (nextNum == 0 && fileExist) 
        {
            // the file name exist without (1)
            fileNameWE = $"{fileNameWE}(1)";
            return fileNameWE + fileExtension;
        }
        else
        {
            var haveParentheses = Regex.Match(fileNameWE, pattern);

            if (haveParentheses.Success)
            {
                // we need to reset the nextNum
                nextNum = 1; 
            }

            // return the new unique name with suffix
            fileNameWE = string.Format("{0}({1})", fileNameWE, nextNum);
            return fileNameWE + fileExtension;
        }
}
  • 我在网上找到的所有解决方案都是使用GUIDDateTime
  • 保持文件名的唯一性
  • 对于我检查功能正常工作并返回“正常”文件名的其他情况。

一些例子:

  • 该文件夹包含:
    • army.png

我想上传:army.png

  • 该文件夹将包含:
    • army.png
    • 军队(1).PNG

我想再次上传:army.png

  • 该文件夹将包含:
    • army.png
    • 军队(1).PNG
    • 军队(2).PNG

我想上传:army(2).png

  • 该文件夹将包含:
    • army.png
    • 军队(1).PNG
    • 军队(2).PNG
    • 军队(2)(1).PNG

我想再次上传:army(2).png

  • 该文件夹将包含:
    • army.png
    • 军队(1).PNG
    • 军队(2).PNG
    • 军队(2)(1).PNG
    • 军队(2)(2).PNG

我想再次上传:army(2).png

  • 该文件夹将包含:
    • army.png
    • 军队(1).PNG
    • 军队(2).PNG
    • 军队(2)(1).PNG
    • 军队(2)(2).PNG
    • 军队(2)(3).PNG

我想上传:army(2)(2).png

  • 该文件夹将包含:
    • army.png
    • 军队(1).PNG
    • 军队(2).PNG
    • 军队(2)(1).PNG
    • 军队(2)(2).PNG
    • 军队(2)(3).PNG
    • 军队(2)(2)(1).PNG

如何修复该函数以便返回正确的字符串?

3 个答案:

答案 0 :(得分:3)

最终版

这是根据问题的所有案例进行测试和运作的:

public static string GetUniqueName(string fileName)
{
    string dir = @"C:\Users\support\Desktop\Zohar\SO\Upload\Target";
    var targetPath = Path.Combine(dir, fileName);
    string fileExtension = Path.GetExtension(targetPath);
    string fileNameWE = Path.GetFileNameWithoutExtension(targetPath);
    int i = 1;
    while (File.Exists(targetPath))
    {
        fileName = string.Format("{0}({1}){2}", fileNameWE, i, fileExtension);
        targetPath = Path.Combine(dir, fileName);
        i++;
    }
    return targetPath;
}

答案 1 :(得分:1)

好的,遗憾的是我在你的海报算法中找不到问题,但是我写了一个新问题,并且我测试了几个名字。似乎正在努力。请检查:

public static string GetUniqueName(string fileName)
{
    var dir = Globals.Directories.GetCustomCategoryThumbnailDir();

    var fileExtension = Path.GetExtension(fileName);
    var fileNameWE = Path.GetFileNameWithoutExtension(fileName);
    var files = Directory.GetFiles(dir, "*" + fileExtension)
        .Select(Path.GetFileName)
        .Where(w => w.StartsWith(fileNameWE)) // included condition.
        .ToArray();

    if (!files.Any()) return fileName;

    var pattern = fileNameWE
        .Select(s => "[" + s + "]")
        .Aggregate("", (ac, i) => ac + i);

    var regex = new Regex(pattern + @"[(](?<counter>\d)[)]");

    var previous = files
        .Select(file => regex.Match(file))
        .Where(match => match.Success)
        .OrderByDescending(match => int.Parse(match.Groups["counter"].Value))
        .FirstOrDefault();

    var correctIndex = previous != null
        ? int.Parse(previous.Groups["counter"].Value) + 1
        : 1;

    return fileNameWE + "(" + correctIndex + ")" + fileExtension;
}

TEST Scenarios:

army(2).png -> army(2)(2).png
army.png -> army(3).png
army(1).png -> army(1)(1).png

答案 2 :(得分:0)

听起来你应该跑一个循环吧?

var fileName = fileNameWE + fileExtension;

while(File.Exists(Path.Combine(dir, fileName)))
{
  fileNameWE += "(1)";
  fileName = fileNameWE + fileExtension;
} 

return fileName;