2012-10-24 39 views
42

Mein C# -Code generiert mehrere Textdateien basierend auf Eingabe und speichert diese in einem Ordner. Außerdem nehme ich an, dass der Name der Textdatei der Eingabe entspricht (die Eingabe enthält nur Buchstaben) Wenn zwei Dateien den gleichen Namen haben, überschreibt sie einfach die vorherige Datei. Aber ich möchte beide Dateien behalten.Automatisches Umbenennen einer Datei, wenn sie bereits in Windows existiert

Ich möchte keine aktuelle Datum Uhrzeit oder eine zufällige Zahl an den zweiten Dateinamen anhängen. Stattdessen möchte ich es genauso machen wie Windows. Wenn der Name der ersten Datei AAA.txt ist, dann ist der zweite Dateiname AAA (2) .txt, der dritte Dateiname ist AAA (3) .txt ..... N der Dateiname ist 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 ?     
      } 
     } 

Antwort

102

Dies überprüft die Existenz von Dateien mit tempFileName und erhöht die Zahl um eins, bis ein Name gefunden wird, der nicht im Verzeichnis existiert.

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

Dateierweiterungen würden falsch angezeigt werden, zB ** C: \ file.txt ** würde ** C: \ file.txt (1) ** "etc. – flindeberg

+4

@flindeberg good catch. Ich glaube, ich habe das korrigiert – cadrell0

+4

Für zukünftige Ref. ein kleiner Haken zu beachten: Wenn die Datei, die überprüft wird, benannt ist wie ein Name (1) etwas mehr text.txt und die Datei existiert bereits, wenn aufgefordert, beide Dateien Windows zu halten Umbenennen Sie die Datei 'irgendeinen Namen (2) etwas mehr text.txt' und nicht' irgendeinen Namen (1) etwas mehr Text (1) .txt', als der obige Code stattdessen würde. –

1

Wie wäre es einfach:

int count = 1; 
String tempFileName = newFileName; 

foreach (var item in allFiles) 
{ 
    if (tempFileName.Equals(item, StringComparison.InvariantCultureIgnoreCase)) 
    { 
    tempFileName = String.Format("{0}({1})", newFileName, count++); 
    } 
} 

Dies wird den ursprünglichen Dateinamen verwenden, wenn er nicht da ist, wenn es nicht (obwohl dieser Code isn einen neuen Dateinamen in Klammern mit dem Index werden Die Erweiterung nicht berücksichtigen. Wenn der neu erzeugte Name "text (001)" verwendet wird, wird er erhöht, bis er einen gültigen unbenutzten Dateinamen findet.

+2

Sie müssen die Anzahl erhöhen. Außerdem wird 'tempFileName' nicht erneut mit vorherigen Elementen verglichen. Daher könnte 'tempFileName' in ein Element geändert werden, das bereits überprüft und übergeben wurde. – cadrell0

+0

@ cadrell0: oops danke ... das war der Plan! Zu schnell tippen. – Ian

+1

Dies berücksichtigt nicht die Dateierweiterung. Ich habe unten ein anderes Beispiel veröffentlicht. – Phill

3

Die anderen Beispiele berücksichtigen den Dateinamen/die Erweiterung nicht.

Hier gehen Sie:

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

Sie eine Dictionary<string,int> erklären können die Anzahl der einzelnen Root-Dateinamen gespeichert wurde zu halten. Danach wird auf Ihrer Save Methode, erhöhen nur den Zähler und hängen Sie ihn an der Basisdateiname:

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]) 
} 

Auf diese Weise werden Sie für jede einzelne Dateinamen einen Zähler haben: AAA (1), AAA (2); BBB (1) ...

0

Es funktioniert jetzt gut. Danke Jungs für die Antworten ..

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"; 
0
int count= 0; 

Datei der Name der Datei Mit diesem Code

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

Woher bekommen Sie 'tempno' aus? – Frecklefoot

11

ist, wenn Dateiname lautet "Test (3) .txt" dann wird es „Test wird (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; 
} 
1
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); 
    } 
+1

Während dies eine Lösung für die Frage bieten könnte, wäre es besser, wenn Sie einige Erläuterungen oder Erklärungen dazu liefern könnten, wie Ihr Code funktioniert oder welche Stärken/Schwächen er hat , etc. –

1

Ich war auf der Suche nach einer Lösung, die eine Datei bewegen würde, und stellen Sie sicher, dass, wenn der Name der Zieldatei nicht bereits vergeben ist. Es würde der gleichen Logik wie Windows folgen und eine Zahl mit Klammern nach der doppelten Datei anhängen.

Die Top-Antwort, dank @ cadrell0, half mir auf die folgende Lösung kommen:

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

Hinsichtlich Giuseppe Kommentar über die Art und Weise Windows umbenennt Dateien, die ich auf einer Version gearbeitet, die alle vorhandenen Index findet das heißt(2) im Dateinamen und benennt die Datei entsprechend Windows entsprechend um. Es wird davon ausgegangen, dass der sourceFileName gültig ist und der Benutzer Schreibrechte für den Zielordner an diesem Punkt hat:

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); 
    } 
Verwandte Themen