FileUpload – 如果文件名存在,则在名称末尾的括号之间连接一个数字
我想将文件(一次一个)上传到文件夹:
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; } }
- 我在网上找到的所有解决方案都是使用
GUID
或DateTime
保持文件名唯一 - 对于我检查function正常工作的其他情况,将返回一个“好”的文件名。
一些例子:
- 该文件夹包含:
- 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
如何修复该函数以便返回正确的字符串?
好吧,不幸的是我在你的海报算法中找不到问题,但是我写了一个新问题,并且我测试了几个名字。 似乎正在努力。 请检查一下:
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 + @"[(](?\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; }
测试场景:
army(2).png -> army(2)(2).png
army.png -> army(3).png
army(1).png -> army(1)(1).png
最终版本
这是根据问题的所有案例进行测试和工作:
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; }
听起来你应该只运行一个循环,对吧?
var fileName = fileNameWE + fileExtension; while(File.Exists(Path.Combine(dir, fileName))) { fileNameWE += "(1)"; fileName = fileNameWE + fileExtension; } return fileName;