2012-10-24 19 views
42

Il mio codice C# sta generando diversi file di testo in base all'input e salvando quelli in una cartella. Inoltre, suppongo che il nome del file di testo sia uguale all'input (l'input contiene solo lettere) Se due file hanno lo stesso nome, significa semplicemente sovrascrivere il file precedente. Ma voglio mantenere entrambi i file.Rinomina automaticamente un file se già esiste in modo Windows

Non voglio aggiungere l'ora della data corrente o un numero casuale al 2 ° nome del file. Invece voglio farlo allo stesso modo di Windows. Se il nome del file principale è AAA.txt, il secondo nome file è AAA (2) .txt, il nome del terzo file sarà AAA (3) .txt ..... Il nome del file sarà 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 ?     
      } 
     } 

risposta

102

Verificherà l'esistenza di file con tempFileName e incrementerà il numero di uno finché non trova un nome che non esiste nella directory.

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

Le estensioni dei file risulterebbero errate, ex ** C: \ file.txt ** diventerebbe ** C: \ file.txt (1) ** "ecc. – flindeberg

+4

@flindeberg buona cattura. Credo di aver corretto questo errore – cadrell0

+4

Per un futuro ref. un po 'di cui essere a conoscenza: se il file che si sta controllando è chiamato come 'some name (1) some more text.txt' e il file esiste già, se viene richiesto di mantenere entrambi i file Windows rinominerà il file 'some name (2) some more text.txt' e non' some name (1) some more text (1) .txt' come invece farebbe il codice sopra. –

1

ne dite solo:

int count = 1; 
String tempFileName = newFileName; 

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

Questa utilizzerà il nome del file originale, se non c'è, se non ci vorrà un nuovo nome di file con l'indice fra parentesi (anche se questo codice isn t prendere in considerazione l'estensione). Se viene utilizzato il nome appena generato "text (001)", verrà incrementato fino a trovare un nome file inutilizzato valido.

+2

È necessario incrementare conteggio. Inoltre, 'tempFileName' non viene ricontrollato rispetto agli elementi precedenti. Così 'tempFileName' potrebbe essere cambiato in un oggetto che è già stato controllato e passato. – cadrell0

+0

@ cadrell0: oops grazie ... questo era il piano! Digitando troppo velocemente. – Ian

+1

Questo non tiene conto dell'estensione del file. Ho pubblicato un esempio diverso di seguito. – Phill

3

Gli altri esempi non tengono conto del nome file/dell'estensione.

Qui si va:

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

è possibile dichiarare una Dictionary<string,int> per mantenere il numero di volte in cui ogni nome di file di root è stato salvato. Dopo di che, sul metodo di Save, solo aumentare il contatore e aggiungerlo al nome del file di base:

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

In questo modo, avrete un contatore per ogni nome di file distinte: AAA (1), AAA (2); BBB (1) ...

0

Ora funziona bene. Grazie ragazzi per le risposte ..

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; 

file è il nome del file di

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

Da dove viene il 'tempno'? – Frecklefoot

11

Con questo codice, se il nome del file è "Test (3) .txt" poi diventerà "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; 
} 
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

Sebbene questo possa fornire una soluzione alla domanda, sarebbe meglio se tu potessi fornire qualche elaborazione o spiegazione su come funziona il tuo codice, o su eventuali punti di forza/difetti che potrebbe avere , eccetera. –

1

ero alla ricerca di una soluzione che spostare un file, e fare in modo che se il nome del file di destinazione non è già stato preso. Seguirà la stessa logica di Windows e aggiungerà un numero, con parentesi dopo il file duplicato.

La risposta superiore, grazie a @ cadrell0, mi ha aiutato arrivare alla seguente soluzione:

/// <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

Per quanto riguarda il commento di Giuseppe sul modo in cui Windows rinomina i file ho lavorato su una versione che trova alcun indice esistente vale a dire(2) nel nome del file e rinomina il file secondo Windows di conseguenza. Il SourceFileName viene considerato valido e l'utente si assume di avere i permessi di scrittura sulla cartella di destinazione da questo punto:

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); 
    } 
Problemi correlati