简体   繁体   English

File.Move()重命名不起作用

[英]File.Move() rename not working

My app takes "unclean" file names and "cleans" them up. 我的应用程序使用“不干净”的文件名并“清理”它们。 "Unclean" file names contain characters like @, #, ~, +, %, etc. The "cleaning" process replaces those chars with "". “不干净”文件名包含@,#,〜,+,%等字符。“清理”过程将这些字符替换为“”。 However, I found that if there are two files in the same folder that, after a cleaning, will have the same name, my app does not rename either file. 但是,我发现,如果同一文件夹中有两个文件,那么清理后它们将具有相同的名称,则我的应用程序不会重命名这两个文件。 (Ie ##test.txt and ~test.txt will both be named test.txt after the cleaning). (即## test.txt和〜test.txt在清洗后都将被命名为test.txt)。

Therefore, I put in a loop that basically checks to see if the file name my app is trying to rename already exists in the folder. 因此,我放入了一个循环,该循环基本上检查了我的应用程序试图重命名的文件名是否已存在于该文件夹中。 However, I tried running this and it would not rename all the files. 但是,我尝试运行此文件,它不会重命名所有文件。 Am I doing something wrong? 难道我做错了什么?

Here's my code: 这是我的代码:

        public void FileCleanup(List<string> paths)
    {
        string regPattern = (@"[~#&!%+{}]+");
        string replacement = "";

        Regex regExPattern = new Regex(regPattern);
        List<string> existingNames = new List<string>();
        StreamWriter errors = new StreamWriter(@"C:\Documents and Settings\joe.schmoe\Desktop\SharePointTesting\Errors.txt");
        StreamWriter resultsofRename = new StreamWriter(@"C:\Documents and Settings\joe.schmoe\Desktop\SharePointTesting\Results of File Rename.txt");

        var filesCount = new Dictionary<string, int>();
        string replaceSpecialCharsWith = "_";

        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))
                {
                    System.IO.File.Move(files2, sanitized);
                    resultsofRename.Write("Path: " + pathOnly + " / " + "Old File Name: " + filenameOnly + "New File Name: " + sanitized + "\r\n" + "\r\n");   
                }

                else 
                {
                    existingNames.Add(sanitized);
                    foreach (string names in existingNames)
                    {

                        string sanitizedPath = regExPattern.Replace(names, replaceSpecialCharsWith);
                        if (filesCount.ContainsKey(sanitizedPath))
                        {
                            filesCount[names]++;
                        }
                        else
                        {
                            filesCount.Add(sanitizedPath, 1);
                        }

                        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);
                        System.IO.File.Move(names, newFileName);

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

            }

    }

}

Anybody have ANY idea why my code won't rename duplicate files uniquely? 有人知道为什么我的代码不会唯一地重命名重复的文件吗?

  • You do foreach (string names in existingNames) , but existingNames is empty. 您进行了foreach (string names in existingNames) ,但是existingNames为空。
  • You have your if (System.IO.File.Exists(sanitized)) backwards: it makes up a new name if the file doesn't exist, instead of when it exists. 您的if (System.IO.File.Exists(sanitized))向后:如果文件不存在(而不是存在时),它将组成一个新名称。
  • You make a string newFileName , but still use sanitizedPath instead of newFileName to do the renaming. 您创建一个字符串newFileName ,但仍使用sanitizedPath而不是newFileName来进行重命名。
  • The second parameter to filesCount.Add(sanitizedPath, 0) should be 1 or 2. After all, you have then encountered your second file with the same name. filesCount.Add(sanitizedPath, 0)的第二个参数应该为1或2。毕竟,您然后遇到了具有相同名称的第二个文件。
  • If filesCount[sanitizedPath] equals 0, you don't change the filename at all, so you overwrite the existing file. 如果filesCount[sanitizedPath]等于0,则根本不更改文件名,因此将覆盖现有文件。

In addition to the problem pointed out by Sjoerd, it appears that you are checking to see if the file exists and if it does exist you move it. 除了Sjoerd指出的问题外,您似乎还在检查文件是否存在以及是否存在,请移动它。 Your if statement should be 您的if陈述应为

     if (!System.IO.File.Exists(sanitized))
     {
         ...
     }    
     else 
     {
         foreach (string names in existingNames)
             {
                 ...    
             }
         }
     }

Update: 更新:

I agree that you should split the code up into smaller methods. 我同意您应该将代码分成较小的方法。 It will help you identify which pieces are working and which aren't. 它将帮助您确定哪些部分有效,哪些无效。 That being said, I would get rid of the existingNames list. 话虽如此,我将摆脱现存的名称列表。 It is not needed because you have the filesCount Dictionary. 因为您有filesCount字典,所以不需要它。 Your else clause would then look something like this: 您的else子句将如下所示:

     if (filesCount.ContainsKey(sanitized))
     {
         filesCount[sanitized]++;
     }
     else
     {
       filesCount.Add(sanitized, 1);
     }

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

     string newFilePath = Path.Combine(Path.GetDirectoryName(sanitized), newFileName);
     System.IO.File.Move(files2, newFileName);

Please note that I changed your String.Format method call. 请注意,我更改了您的String.Format方法调用。 You had some commas and spaces in there that looked incorrect for building a path, although I could be missing something in your implementation. 尽管其中可能会缺少一些逗号和空格,但这些逗号和空格对于构建路径来说似乎是不正确的。 Also, in the Move I changed the first argument from "names" to "files2". 另外,在“移动”中,我将第一个参数从“名称”更改为“ files2”。

A good way to make the code less messy would be to split it to methods as logical blocks. 减少代码混乱的一个好方法是将其拆分为逻辑块的方法。

FindUniqueName(string filePath, string fileName);
The method would prefix the fileName with a character, until the fileName is unique withing the filePath . 该方法将在fileName添加一个字符,直到fileName与filePath唯一。

MoveFile(string filePath, string from, string to);
The method would use the FindUniqueName method if the file already exists. 如果文件已经存在,则该方法将使用FindUniqueName方法。

It would be way easier to test the cleanup that way. 以这种方式测试清除会更容易。

Also you should check if a file actually requires renaming : 另外,您还应该检查文件是否确实需要重命名

if (String.Compare(sanitizedFileName, filenameOnly, true) != 0)
  MoveFile(pathOnly, fileNameOnly, sanitizedFileName);

private string FindUniqueName(string fileDirectory, string from, string to)
{
    string fileName = to;

    // There most likely won't be that many files with the same name to reach max filename length.
    while (File.Exists(Path.Combine(fileDirectory, fileName)))
    {
        fileName = "_" + fileName;
    }

    return fileName;
}

private void MoveFile(string fileDirectory, string from, string to)
{
    to = FindUniqueName(fileDirectory, from, to);

    File.Move(Path.Combine(fileDirectory, from), Path.Combine(fileDirectory, to));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM