2010-06-30 71 views
1

我有這樣的代碼:問題與現有的文件名和創建一個唯一的文件名

public void FileCleanup(List<string> paths) 
    { 
     string regPattern = (@"[~#&!%+{}]+"); 
     string replacement = ""; 
     string replacement_unique = "_"; 
     Regex regExPattern = new Regex(regPattern); 
     List<string> existingNames = new List<string>(); 
     StreamWriter errors = new StreamWriter(@"C:\Documents and Settings\jane.doe\Desktop\SharePointTesting\Errors.txt"); 
     StreamWriter resultsofRename = new StreamWriter(@"C:\Documents and Settings\jane.doe\Desktop\SharePointTesting\Results of File Rename.txt"); 
     foreach (string files2 in paths) 

      try 
      { 
       string filenameOnly = Path.GetFileName(files2); 
       string pathOnly = Path.GetDirectoryName(files2); 
       string sanitizedFileName = regExPattern.Replace(filenameOnly, replacement); 
       string sanitized = Path.Combine(pathOnly, sanitizedFileName); 
       if (!System.IO.File.Exists(sanitized)) 
       { 
        existingNames.Add(sanitized); 
        try 
        { 
         foreach (string names in existingNames) 
         { 
          string filename = Path.GetFileName(names); 
          string filepath = Path.GetDirectoryName(names); 
          string cleanName = regExPattern.Replace(filename, replacement_unique); 
          string scrubbed = Path.Combine(filepath, cleanName); 
          System.IO.File.Move(names, scrubbed); 
          //resultsofRename.Write("Path: " + pathOnly + "/" + "Old File Name: " + filenameOnly + "New File Name: " + sanitized + "\r\n" + "\r\n"); 
          resultsofRename = File.AppendText("Path: " + filepath + "/" + "Old File Name: " + filename + "New File Name: " + scrubbed + "\r\n" + "\r\n"); 

         } 
        } 
        catch (Exception e) 
        { 
         errors.Write(e); 
        } 

       } 
       else 
       { 
        System.IO.File.Move(files2, sanitized); 
        resultsofRename.Write("Path: " + pathOnly + "/" + "Old File Name: " + filenameOnly + "New File Name: " + sanitized + "\r\n" + "\r\n"); 
       } 


      } 
      catch (Exception e) 
      { 
       //write to streamwriter 
      } 
     } 
    } 
} 

什麼,我想在這裏做的是通過除去無效字符(在正則表達式定義)重命名「髒」的文件名,用「」替換它們。不過,我注意到如果我有重複的文件名,應用程序不會重命名它們。即如果我在同一個文件夾中有## test.txt和~~ test.txt,它們將被重命名爲test.txt。所以,我創建了另一個foreach循環,用一個「_」替代了無效字符而不是空格。

問題是,每當我試圖運行這個,沒有結果發生!沒有文件被重命名!

有人可以告訴我,如果我的代碼是不正確的,如何解決它?

也有人知道我怎麼能替換第二個foreach循環中的無效字符與每次不同的字符?這樣,如果有多個實例,即%Test.txt,〜Test.txt和#test.txt(全部要重命名爲test.txt),它們可以以不同的方式用不同的char來唯一命名?

+0

這可能是因爲那些骯髒的名字損害你的執行。最重要的是給我們例外信息。 – eugeneK 2010-06-30 13:20:51

+0

您是否調試過代碼以縮小問題的嚴重程度? – 2010-06-30 13:21:22

+0

我做了一個編輯 - 我想出了爲什麼我的代碼沒有步進到第二個foreach循環。但是,您是否知道如何每次使用不同的唯一字符替換無效字符,以便每個文件名都保持唯一? – yeahumok 2010-06-30 13:26:46

回答

1

但是,您是否知道如何每次都用不同的唯一字符替換無效字符,以便每個文件名都保持唯一?

這是一種方式:

char[] uniques = ",'%".ToCharArray(); // whatever chars you want 
foreach (string file in files) 
{ 
    foreach (char c in uniques) 
    { 
     string replaced = regexPattern.Replace(file, c.ToString()); 
     if (File.Exists(replaced)) continue; 
     // create file 
    } 
} 

當然,您可能需要重構到它自己的方法這一點。還要注意,只有唯一字符不同的文件的最大數量限制爲uniques陣列中的字符數,因此如果有許多具有相同名稱的文件僅與您列出的特殊字符不同,則可能是明智地使用不同的方法,例如將一個數字附加到文件名的末尾。

我怎麼會追加一個數字,文件名的最後(具有不同#每次?)

一個喬希的建議會的工作,跟蹤修改後的文件名的稍微修改版本映射到更換後的相同的文件名已經產生的次數:

var filesCount = new Dictionary<string, int>(); 
string replaceSpecialCharsWith = "_"; // or "", whatever 
foreach (string file in files) 
{ 
    string sanitizedPath = regexPattern.Replace(file, replaceSpecialCharsWith); 
    if (filesCount.ContainsKey(sanitizedPath)) 
    { 
     filesCount[file]++; 
    } 
    else 
    { 
     filesCount.Add(sanitizedPath, 0); 
    } 

    string newFileName = String.Format("{0}{1}{2}", 
       Path.GetFileNameWithoutExtension(sanitizedPath), 
       filesCount[sanitizedPath] != 0 
        ? filesCount[sanitizedPath].ToString() 
        : "", 
       Path.GetExtension(sanitizedPath)); 

    string newFilePath = Path.Combine(Path.GetDirectoryName(sanitizedPath), 
             newFileName); 
    // create file... 
} 
+0

我如何將一個數字追加到文件名的末尾(每次都使用不同的#) – yeahumok 2010-06-30 13:45:56

1

只是一個建議

船尾如果刪除/替換特殊字符,則會將時間戳添加到文件名中。時間戳是唯一的,因此將它們附加到文件名將爲您提供唯一的文件名。

+0

對於所有文件我都無法完全達到 - 基本上我的應用程序是通過合法文檔遞歸的,所以名稱必須儘可能地保持原樣。然而,這可能是一個很好的方式,使我的第二個foreach循環中重複的名稱是唯一的! – yeahumok 2010-06-30 13:51:41

+0

在使用該文件之前,可以總是從文件名的末尾剝離時間戳,因此您將獲得原始文件名。 例如:text_123456789.txt explode('_',text_123456789.txt)會給你文本和爆炸('。',text_123456789.txt)會給你txt – Crazyshezy 2010-06-30 14:10:37

+0

更好的主意是預先安排時間戳(例如:123456789_text.txt )然後爆炸獲取文件名稱,只要需要 – Crazyshezy 2010-06-30 14:26:30

1

如何維護一個所有重命名文件的字典,檢查每個文件對它,如果已經存在添加一個數字到它的末尾?

+0

啊,這聽起來像一個偉大的想法 - 但我不太確定如何實施。我對C#很新! – yeahumok 2010-06-30 13:52:22

1

爲響應答案@Josh斯密頓的位置給了一個使用字典來跟蹤文件名的一些示例代碼: -

class Program 
{ 

    private static readonly Dictionary<string,int> _fileNames = new Dictionary<string, int>(); 

    static void Main(string[] args) 
    { 

     var fileName = GetUniqueFileName("filename.txt"); 
     Console.WriteLine(fileName); 

     fileName = GetUniqueFileName("someotherfilename.txt"); 
     Console.WriteLine(fileName); 

     fileName = GetUniqueFileName("filename.txt"); 
     Console.WriteLine(fileName); 

     fileName = GetUniqueFileName("adifferentfilename.txt"); 
     Console.WriteLine(fileName); 

     fileName = GetUniqueFileName("filename.txt"); 
     Console.WriteLine(fileName); 

     fileName = GetUniqueFileName("adifferentfilename.txt"); 
     Console.WriteLine(fileName); 

     Console.ReadLine(); 
    } 

    private static string GetUniqueFileName(string fileName) 
    {    

     // If not already in the dictionary add it otherwise increment the counter 
     if (!_fileNames.ContainsKey(fileName)) 
      _fileNames.Add(fileName, 0); 
     else 
      _fileNames[fileName] += 1; 

     // Now return the new name using the counter if required (0 means it's just been added) 
     return _fileNames[fileName].ToString().Replace("0", string.Empty) + fileName;    
    } 
} 
+0

+1:謝謝 - 我一定是指這個以供將來參考! – yeahumok 2010-06-30 20:04:28

相關問題