递归?或者如何让父母成为父母?

时间:2013-01-15 18:35:42

标签: c# winforms recursion

之前我发布了这个,但不得不删除这个问题,因为我解释得非常糟糕,对于那些可能以前读过的人感到遗憾。让我更清楚一点。我必须创建一个winform应用程序,允许通过指定三个内容将文件从一个目录复制到另一个目录:

  1. (txtPath)
  2. 复制的位置
  3. 要复制的文件扩展名(您指定的文件扩展名是复制的文件扩展名)(txtExtensions)
  4. 在何处复制到(txtArchiveTo)
  5. 视觉上看起来像这样:

    enter image description here

    从txtPath到txtArchiveTo的副本必须与它的复制方式相匹配。如果txtPath如下所示:

    c:\temp
      |
       -drivers.exe (file)
       -log.txt (file)
       -\Test1 (directory)
       -\Test2 (directory)
    

    然后,如果我为txtArchiveTo选择一个文件夹,例如c:\backup,结果应该在我的程序运行之后,它应该如下所示:

    c:\backup
      |
       -\temp
          |
           -drivers.exe (file)
           -log.txt (file)
           -\Test1 (directory)
           -\Test2 (directory)
    

    这就是复制的内容需要遵循相同的结构......但是我很难对此进行编码,因为它看起来好像我一直在引用root.Parent.Parent等等。让我发布一些代码:

    Go按钮非常基本:

    private void btnGo_Click(object sender, EventArgs e)
    {
        DirectoryInfo di = new DirectoryInfo(txtPath.Text);
        WalkDirectoryTree(di);
    }
    

    这只是创建一个directoryinfo对象,所以我有txtPath目录的句柄并调用函数WalkDirectoryTree。该功能如下所示:

     private void WalkDirectoryTree(DirectoryInfo root)
            {
                System.IO.FileInfo[] files = null;
                System.IO.DirectoryInfo[] subDirs = null;
    
                string[] extArray = txtExtensions.Text.Split(' '); //to hold the txtExtensions as an array string { "txt" "tar" "zip" etc.. }
                string ext; //to hold the extension
    
                // First, process all the files directly under this folder
                try
                {
                    files = root.GetFiles("*.*");
                }
                catch (UnauthorizedAccessException e)
                {
                    throw; //todo: log this later on...
                }
                catch (System.IO.DirectoryNotFoundException e)
                {
                    Console.WriteLine(e.Message);
                }
    
                if (files != null)
                {
                    foreach (System.IO.FileInfo fi in files)
                    {
                        string extension = fi.Extension.ToString();
                        if (extension.IndexOf(".") > -1)
                            ext = extension.Substring(1, extension.Length-1);
                        else
                            ext = extension;
    
                        if (extArray.Any(s => ext.Contains(s)))
                        {    
                            //copy the file
                            if (Directory.Exists(txtArchiveTo.Text + "\\" + fi.Directory.Name))
                                {
                                    //directory exists copy the files
                                }
                                else
                                {
                                    Directory.CreateDirectory(txtArchiveTo.Text + "\\" + fi.Directory.Name);
                                }
    
                                File.Copy(fi.FullName, txtArchiveTo.Text + "\\" + fi.Directory.Name + "\\" + fi.Name);                    
    
                            //create a shortcut pointing back to the file...
                            using (ShellLink shortcut = new ShellLink())
                            {
                                shortcut.Target = fi.FullName;
                                //shortcut.Description = "MY SHORTCUT";
                                shortcut.DisplayMode = ShellLink.LinkDisplayMode.edmNormal;
                                shortcut.ShortCutFile = fi.DirectoryName + "\\" + fi.Name + ".lnk";
                                shortcut.Save();
                            }
                        }
    
                    }
    
                    // Now find all the subdirectories under this directory.
                    subDirs = root.GetDirectories();
    
                    foreach (System.IO.DirectoryInfo dirInfo in subDirs)
                    {
                        // Resursive call for each subdirectory.
                        WalkDirectoryTree(dirInfo);
                    }
                }            
            }
    

    请不要太注意我创建快捷方式等的代码。那部分不是问题。我遇到困难的是当我点击这些代码行时:

     if (extArray.Any(s => ext.Contains(s)))
                            {    
                                //copy the file
                                if (Directory.Exists(txtArchiveTo.Text + "\\" + fi.Directory.Name))
                                    {
                                        //directory exists copy the files
                                    }
                                    else
                                    {
                                        Directory.CreateDirectory(txtArchiveTo.Text + "\\" + fi.Directory.Name);
                                    }
    

    if只是检查文件的扩展名是否与用户在txtExtensions内输入的扩展名匹配,这确保我们只复制具有这些扩展名的文件但是在找到的文件夹中。我的问题就在那之后如果...我不能只说:

    Directory.CreateDirectory(txtArchiveTo.Text + "\\" + fi.Directory.Name);

    原因是存档文件夹必须与要复制的文件夹路径相同。因此,例如,如果有人选择c:\ temp来搜索并找到要复制的txt文件,他们选择了一个文件夹c:\ backup复制到,而c:\ temp有3个子文件夹(一,二和三)也包含文本文件。结果是在我的程序运行(完成“Go”)后,结果将是存档文件夹c:\ backup将包含其中包含txt文件的文件夹(一,二和三),此外,c:\ backup \ One \ mytest.txt等。

    我想在我当前的代码中加入它,并且觉得我非常接近,但我认为我需要想出一些反复来获得正确的目录结构。请不要发布我关于如何使用Directory.CreateDirectory或FileInfo类的MSDN链接,我已阅读并理解它们。

1 个答案:

答案 0 :(得分:2)

将目的地文件夹作为参数传递给步行功能:

    private void WalkDirectoryTree(DirectoryInfo root, string DestinationFolder)

然后在复制文件时,只需使用fileInfo的CopyTo方法:

     fi.CopyTo(DestinationFolder)

以递归方式调用下一个方法时,您只需添加到desintation路径:

    foreach (System.IO.DirectoryInfo dirInfo in subDirs)
    {
        // Resursive call for each subdirectory.
        WalkDirectoryTree(dirInfo, System.IO.Path.Combine(DestinationFolder, dirInfo.Name));
    }

进行初始调用时,您需要计算输出目录:

string path = txtPath.Text;
string outputDir = txtArchiveTo.Text
string finalDir = System.IO.Path.Combine(outputDir, path.Remove(0, System.IO.Path.GetPathRoot(path).Length));

DirectoryInfo di = new DirectoryInfo(txtPath.Text);
WalkDirectoryTree(di, finalDir);