在我的输出中看到重复项。为什么?

时间:2010-07-13 13:34:51

标签: c#

我的应用程序的输出正在生成重复的文件名...我不是百分之百确定为什么会这样。

我的应用程序通过查找文件名中的正则表达式模式来“清除”文件名。如果没有,则将其转储到“正常”列表中并忽略它。

以下是我用于显示输出的代码:[这一直向我显示文件名的重复!!]

public partial class DriveRecursion_Results : Form
{
    List<string> paths = new List<string>();


    public DriveRecursion_Results()
    {
        InitializeComponent();
    }




    public void DriveRecursion(string retPath)
    {
        string pattern = (@"[~#&!%+{}]+");

        Regex regEx = new Regex(pattern);

        string[] fileDrive = Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);

        List<string> normal = new List<string>();
        List<string> fileNameOnlyList = new List<string>();


        dataGridView1.Rows.Clear();
        try
        {
            foreach (string fileNames in fileDrive)
            {
                string strippedFileName = System.IO.Path.GetFileName(fileNames);
                fileNameOnlyList.Add(strippedFileName);

                foreach (string nameOnly in fileNameOnlyList)
                {
                    if (regEx.IsMatch(strippedFileName))
                    {
                        //string fileNameOnly = Path.GetFileName(fileNames);
                        string pathOnly = Path.GetDirectoryName(fileNames);

                        DataGridViewRow dgr = new DataGridViewRow();

                        dgr.CreateCells(dataGridView1);
                        dgr.Cells[0].Value = pathOnly;
                        dgr.Cells[1].Value = nameOnly;
                        dataGridView1.Rows.Add(dgr);
                        string pathforInvalidName = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(nameOnly), pathOnly);


                        paths.Add(pathforInvalidName);


                    }

                    else
                    {
                        normal.Add(strippedFileName);

                    }
                }

            }

        }
        catch (Exception e)
        {
            StreamWriter sw = new StreamWriter(retPath + "ErrorLog.txt");
            sw.Write(e);

        }


    }


    private void button1_Click_1(object sender, EventArgs e)
    {

        this.Close();

        CleanNames clean = new CleanNames();
        clean.Sanitizer(paths);
        clean.Show();



    }

一旦确定需要重命名哪些文件,它就会清除“脏”名称:

public partial class CleanNames : Form
{
    public CleanNames()
    {
        InitializeComponent();

    }

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

        Regex regExPattern = new Regex(regPattern);
        Regex regExPattern2 = new Regex(@"\s{2,}");

        StreamWriter errors = new StreamWriter(@"S:\Test\Errors.txt", true);
        var filesCount = new Dictionary<string, int>();


        dataGridView1.Rows.Clear();

           try
            {

              foreach (string files2 in paths)
              {

                string filenameOnly = System.IO.Path.GetFileName(files2);
                string pathOnly = System.IO.Path.GetDirectoryName(files2);
                string sanitizedFileName = regExPattern.Replace(filenameOnly, replacement);
                sanitizedFileName = regExPattern2.Replace(sanitizedFileName, replacement);
                string sanitized = System.IO.Path.Combine(pathOnly, sanitizedFileName);


                if (!System.IO.File.Exists(sanitizedFileName))
                {
                    DataGridViewRow clean = new DataGridViewRow();
                    clean.CreateCells(dataGridView1);
                    clean.Cells[0].Value = pathOnly;
                    clean.Cells[1].Value = filenameOnly;
                    clean.Cells[2].Value = sanitizedFileName;
                    dataGridView1.Rows.Add(clean);

                    System.IO.File.Move(files2, sanitized);
                }

                else
                {
                    if (filesCount.ContainsKey(sanitizedFileName))
                    {
                        filesCount[sanitized]++;
                    }
                    else
                    {
                        filesCount.Add(sanitized, 1);
                    }
                    string newFileName = String.Format("{0}{1}{2}",
                    System.IO.Path.GetFileNameWithoutExtension(sanitized),
                    filesCount[sanitized].ToString(),
                    System.IO.Path.GetExtension(sanitized));
                    string newFilePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(sanitized), newFileName);
                    newFileName = regExPattern2.Replace(newFileName, replacement);
                    System.IO.File.Move(files2, newFilePath);
                    sanitized = newFileName;

                    DataGridViewRow clean = new DataGridViewRow();
                    clean.CreateCells(dataGridView1);
                    clean.Cells[0].Value = pathOnly;
                    clean.Cells[1].Value = filenameOnly;
                    clean.Cells[2].Value = newFileName;

                    dataGridView1.Rows.Add(clean);

                }




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


    }

    private void SanitizeFileNames_Load(object sender, EventArgs e)
    { }

    private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        Application.Exit();
    }

我在这里尝试做的只是显示需要重命名的文件(不是所有文件)。我想拿这些脏文件名并用我的第二课清理它们。

有人知道为什么我在输出上看到同一文件的倍数?有谁知道如何解决这个问题?!?!

3 个答案:

答案 0 :(得分:5)

我的直接观察是你的foreach (string nameOnly in fileNameOnlyList)循环不应该嵌套在它的位置。你的逻辑看起来像这样。

For each filename:
    Add it to the list.
    For *everything in the list*...

所以你要加一个。然后处理它。然后添加另一个。然后处理两个。然后加。然后处理这三个。等等。

试试这个。

        foreach (string fileNames in fileDrive)
        {
            string strippedFileName = System.IO.Path.GetFileName(fileNames);
            fileNameOnlyList.Add(strippedFileName);
        }

        foreach (string strippedFileName in fileNameOnlyList)
        {
            if (regEx.IsMatch(strippedFileName))
            // ...
        }

修改

更好的是,为什么有两个循环?

        foreach (string fileNames in fileDrive)
        {
            string strippedFileName = System.IO.Path.GetFileName(fileNames);
            fileNameOnlyList.Add(strippedFileName);

            if (regEx.IsMatch(strippedFileName))
            // ...
        }

答案 1 :(得分:0)

我的第一个猜测是你看到重复,因为你在fileNameOnlyList的循环中有fileDrive的循环。当您从fileDrive集合处理第二个文件名时,您也会将第一个文件名添加到数据网格中。

有两种方法可以解决这个问题:   - 将内环移出外环并将其置于其下方   - 删除内部循环(但保留其中的代码)并在代码中使用strippedFileName而不是nameOnly变量

答案 2 :(得分:0)

您通过目录结构递归搜索

Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);

但您只使用文件名

System.IO.Path.GetFileName(fileNames);

因此,如果嵌套文件夹中有相同的文件,它将显示两次。