Автоматически переименовывать файл, если он уже существует в Windows
Мой код С# генерирует несколько текстовых файлов на основе ввода и сохраняет их в папке. Кроме того, я предполагаю, что имя текстового файла будет таким же, как и вход (вход содержит только буквы)
Если два файла имеют одинаковое имя, он просто перезаписывает предыдущий файл.
Но я хочу сохранить оба файла.
Я не хочу добавлять текущее время или случайное число ко второму имени файла. Вместо этого я хочу сделать это так же, как Windows. Если имя файла fisrt равно AAA.txt, второе имя файла - AAA (2).txt, третьим именем будет AAA (3).txt..... N-м именем файла будет AAA (N).txt.
string[] allFiles = Directory.GetFiles(folderPath).Select(filename => Path.GetFileNameWithoutExtension(filename)).ToArray();
foreach (var item in allFiles)
{
//newFileName is the txt file which is going to be saved in the provided folder
if (newFileName.Equals(item, StringComparison.InvariantCultureIgnoreCase))
{
// What to do here ?
}
}
Ответы
Ответ 1
Это проверит наличие файлов с tempFileName и увеличит число на единицу, пока не найдет имя, которое не существует в каталоге.
int count = 1;
string fileNameOnly = Path.GetFileNameWithoutExtension(fullPath);
string extension = Path.GetExtension(fullPath);
string path = Path.GetDirectoryName(fullPath);
string newFullPath = fullPath;
while(File.Exists(newFullPath))
{
string tempFileName = string.Format("{0}({1})", fileNameOnly, count++);
newFullPath = Path.Combine(path, tempFileName + extension);
}
Ответ 2
С этим кодом, если filename является "Test (3).txt", тогда он станет "Test (4).txt".
public static string GetUniqueFilePath(string filepath)
{
if (File.Exists(filepath))
{
string folder = Path.GetDirectoryName(filepath);
string filename = Path.GetFileNameWithoutExtension(filepath);
string extension = Path.GetExtension(filepath);
int number = 1;
Match regex = Regex.Match(filepath, @"(.+) \((\d+)\)\.\w+");
if (regex.Success)
{
filename = regex.Groups[1].Value;
number = int.Parse(regex.Groups[2].Value);
}
do
{
number++;
filepath = Path.Combine(folder, string.Format("{0} ({1}){2}", filename, number, extension));
}
while (File.Exists(filepath));
}
return filepath;
}
Ответ 3
Другие примеры не учитывают имя файла/расширение.
Здесь вы идете:
public static string GetUniqueFilename(string fullPath)
{
if (!Path.IsPathRooted(fullPath))
fullPath = Path.GetFullPath(fullPath);
if (File.Exists(fullPath))
{
String filename = Path.GetFileName(fullPath);
String path = fullPath.Substring(0, fullPath.Length - filename.Length);
String filenameWOExt = Path.GetFileNameWithoutExtension(fullPath);
String ext = Path.GetExtension(fullPath);
int n = 1;
do
{
fullPath = Path.Combine(path, String.Format("{0} ({1}){2}", filenameWOExt, (n++), ext));
}
while (File.Exists(fullPath));
}
return fullPath;
}
Ответ 4
Как насчет просто:
int count = 1;
String tempFileName = newFileName;
foreach (var item in allFiles)
{
if (tempFileName.Equals(item, StringComparison.InvariantCultureIgnoreCase))
{
tempFileName = String.Format("{0}({1})", newFileName, count++);
}
}
Это будет использовать исходное имя файла, если оно не существует, если оно не будет содержать новое имя файла с индексом в скобках (хотя этот код не учитывает расширение). Если используется новое сгенерированное имя "текст (001)", оно будет увеличиваться до тех пор, пока не найдет допустимое неиспользуемое имя файла.
Ответ 5
public static string AutoRenameFilename(FileInfo file)
{
var filename = file.Name.Replace(file.Extension, string.Empty);
var dir = file.Directory.FullName;
var ext = file.Extension;
if (file.Exists)
{
int count = 0;
string added;
do
{
count++;
added = "(" + count + ")";
} while (File.Exists(dir + "\\" + filename + " " + added + ext));
filename += " " + added;
}
return (dir + filename + ext);
}
Ответ 6
Я искал решение, которое переместило бы файл, и убедитесь, что если имя целевого файла еще не выполнено. Он будет следовать той же логике, что и Windows, и добавить число с скобками после дубликата файла.
Главный ответ, благодаря @cadrell0, помог мне прийти к следующему решению:
/// <summary>
/// Generates full file path for a file that is to be moved to a destinationFolderDir.
///
/// This method takes into account the possiblity of the file already existing,
/// and will append number surrounded with brackets to the file name.
///
/// E.g. if D:\DestinationDir contains file name file.txt,
/// and your fileToMoveFullPath is D:\Source\file.txt, the generated path will be D:\DestinationDir\file(1).txt
///
/// </summary>
/// <param name="destinationFolderDir">E.g. D:\DestinationDir </param>
/// <param name="fileToMoveFullPath">D:\Source\file.txt</param>
/// <returns></returns>
public string GetFullFilePathWithDuplicatesTakenInMind(string destinationFolderDir, string fileToMoveFullPath)
{
string destinationPathWithDuplicatesTakenInMind;
string fileNameWithExtension = Path.GetFileName(fileToMoveFullPath);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileToMoveFullPath);
string fileNameExtension = Path.GetExtension(fileToMoveFullPath);
destinationPathWithDuplicatesTakenInMind = Path.Combine(destinationFolderDir, fileNameWithExtension);
int count = 0;
while (File.Exists(destinationPathWithDuplicatesTakenInMind))
{
destinationPathWithDuplicatesTakenInMind = Path.Combine(destinationFolderDir, $"{fileNameWithoutExtension}({count}){fileNameExtension}");
count = count + 1; // sorry, not a fan of the ++ operator.
}
return destinationPathWithDuplicatesTakenInMind;
}
Ответ 7
Вы можете объявить Dictionary<string,int>
, чтобы сохранить количество раз, когда было сохранено имя каждого корневого файла. После этого в вашем методе Save
просто увеличьте счетчик и добавьте его в имя базового файла:
var key = fileName.ToLower();
string newFileName;
if(!_dictionary.ContainsKey(key))
{
newFileName = fileName;
_dictionary.Add(key,0);
}
else
{
_dictionary[key]++;
newFileName = String.Format("{0}({1})", fileName, _dictionary[key])
}
Таким образом, у вас будет счетчик для каждого отдельного имени файла: AAA (1), AAA (2); В (1)...
Ответ 8
Теперь он отлично работает. спасибо ребятам за ответы.
string[] allFiles = Directory.GetFiles(folderPath).Select(filename => Path.GetFileNameWithoutExtension(filename)).ToArray();
string tempFileName = fileName;
int count = 1;
while (allFiles.Contains(tempFileName ))
{
tempFileName = String.Format("{0} ({1})", fileName, count++);
}
output = Path.Combine(folderPath, tempFileName );
string fullPath=output + ".xml";
Ответ 9
int count= 0;
file - это имя файла
while (File.Exists(fullpathwithfilename)) //this will check for existence of file
{
// below line names new file from file.xls to file1.xls
fullpathwithfilename= fullpathwithfilename.Replace("file.xls", "file"+count+".xls");
count++;
}
Ответ 10
Что касается комментария Giuseppe о том, как окна переименовывают файлы, которые я работал над версией, которая находит любой существующий индекс i.e. (2) в имени файла и соответственно переименовывает файл в соответствии с окнами. Предполагается, что sourceFileName является допустимым, и предполагается, что пользователь имеет право на запись в целевой папке:
using System.IO;
using System.Text.RegularExpressions;
private void RenameDiskFileToMSUnique(string sourceFileName)
{
string destFileName = "";
long n = 1;
// ensure the full path is qualified
if (!Path.IsPathRooted(sourceFileName)) { sourceFileName = Path.GetFullPath(sourceFileName); }
string filepath = Path.GetDirectoryName(sourceFileName);
string fileNameWOExt = Path.GetFileNameWithoutExtension(sourceFileName);
string fileNameSuffix = "";
string fileNameExt = Path.GetExtension(sourceFileName);
// if the name includes the text "(0-9)" then we have a filename, instance number and suffix
Regex r = new Regex(@"\(\d+\)");
Match match = r.Match(fileNameWOExt);
if (match.Success) // the pattern (0-9) was found
{
// text after the match
if (fileNameWOExt.Length > match.Index + match.Length) // remove the format and create the suffix
{
fileNameSuffix = fileNameWOExt.Substring(match.Index + match.Length, fileNameWOExt.Length - (match.Index + match.Length));
fileNameWOExt = fileNameWOExt.Substring(0, match.Index);
}
else // remove the format at the end
{
fileNameWOExt = fileNameWOExt.Substring(0, fileNameWOExt.Length - match.Length);
}
// increment the numeric in the name
n = Convert.ToInt64(match.Value.Substring(1, match.Length - 2)) + 1;
}
// format variation: indexed text retains the original layout, new suffixed text inserts a space!
do
{
if (match.Success) // the text was already indexed
{
if (fileNameSuffix.Length > 0)
{
destFileName = Path.Combine(filepath, String.Format("{0}({1}){2}{3}", fileNameWOExt, (n++), fileNameSuffix, fileNameExt));
}
else
{
destFileName = Path.Combine(filepath, String.Format("{0}({1}){2}", fileNameWOExt, (n++), fileNameExt));
}
}
else // we are adding a new index
{
destFileName = Path.Combine(filepath, String.Format("{0} ({1}){2}", fileNameWOExt, (n++), fileNameExt));
}
}
while (File.Exists(destFileName));
File.Copy(sourceFileName, destFileName);
}