2010-06-30 68 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

相关问题