C# 递归?或者,如何让父母继续为人父母?

C# 递归?或者,如何让父母继续为人父母?,c#,winforms,recursion,C#,Winforms,Recursion,我之前发布过这篇文章,但不得不删除这个问题,因为我解释得太可怕了,对不起那些以前可能读过的人。让我更清楚一点。我必须创建一个winform应用程序,通过指定三项内容,允许用户将文件从一个目录复制到另一个目录: 从何处复制(txtPath) 要复制的文件扩展名是什么(您指定的是要复制的文件扩展名)(txtExtensions) 在哪里复制到(txtArchiveTo) 从视觉上看,它是这样的: c:\backup | -\temp | -drivers.exe

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

  • 从何处复制
    (txtPath)
  • 要复制的文件扩展名是什么(您指定的是要复制的文件扩展名)
    (txtExtensions)
  • 在哪里复制到
    (txtArchiveTo)
  • 从视觉上看,它是这样的:

    c:\backup
      |
       -\temp
          |
           -drivers.exe (file)
           -log.txt (file)
           -\Test1 (directory)
           -\Test2 (directory)
    
     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);
                    }
                }            
            }
    

    从txtPath到TXTACHIVOVE的副本必须匹配其复制方式。也就是说,如果
    txtPath
    如下所示:

    c:\temp
      |
       -drivers.exe (file)
       -log.txt (file)
       -\Test1 (directory)
       -\Test2 (directory)
    
    然后,如果我为
    txtarchivevot
    选择一个文件夹,例如
    c:\backup
    ,结果应该是在我的程序运行后,它应该是这样的:

    c:\backup
      |
       -\temp
          |
           -drivers.exe (file)
           -log.txt (file)
           -\Test1 (directory)
           -\Test2 (directory)
    
     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);
                    }
                }            
            }
    
    这就是复制的内容需要遵循相同的结构…但我很难对其进行编码,因为它看起来好像我一直在引用
    root.Parent.Parent
    ,等等。让我发布一些代码:

    Go
    按钮非常基本:

    private void btnGo_Click(object sender, EventArgs e)
    {
        DirectoryInfo di = new DirectoryInfo(txtPath.Text);
        WalkDirectoryTree(di);
    }
    
    这只是创建了一个directoryinfo对象,这样我就有了
    txtPath
    目录的句柄,并调用了一个函数
    WalkDirectoryTree
    。该函数如下所示:

    c:\backup
      |
       -\temp
          |
           -drivers.exe (file)
           -log.txt (file)
           -\Test1 (directory)
           -\Test2 (directory)
    
     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(txtarchive.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的链接,我已经阅读并理解了这些链接。

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

        private void WalkDirectoryTree(DirectoryInfo root, string DestinationFolder)
    
    然后,复制文件时,只需使用fileInfo的CopyTo方法即可:

         fi.CopyTo(DestinationFolder)
    
    递归调用下一个方法时,只需将以下内容添加到指定路径:

        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);
    

    @这不是我的问题…我知道如何递归复制文件。问题是如何维护正确的路径,因为我第一次获取文件。然后,如果出现一个目录,它会调用WalkDirectoryTree,这就是它可以变得很奇怪的地方,因为该目录需要与txtPath处于同一级别…当前路径应该保存在一个变量中。。现在,如果您在当前目录中,那么您应该将基于该扩展名的文件保存到一个数组或列表中,并在该循环中的foreach循环中迭代该列表,然后执行复制操作。这有意义吗?ispiro-我的问题是如何执行复制操作…因为只要我找到一个新目录和“WalkDirectoryTree()”我有了一个新的根目录…基本上副本应该匹配,但进入一个新位置,查看我的现有代码,我可以在那里做些什么来修复它…发布运行
    目录的结果的字符串值。Exists(txtArchiveTo.Text+“\\”+fi.Directory.Name
    使用一个小示例。这样我们就可以了解您的代码是如何工作的,然后发布您真正想要的内容。我应该指出,您的最后一个段落毫无意义。这种工作方式……但请将此结构
    c:\temp\test1
    想象为txtPath。
    txtcarchive
    包含
    c:\backup
    ,之后使用您的代码,结果是
    c:\backup\test1
    ,但它应该是
    c:\backup\temp\test1
    @oJM86o,然后指定c:\backup\temp作为初始调用的根目录WalkDirectoryTree@JohnKoerner我理解,但用户会选择说只是c:\backup。他或她永远不会记得输入c:\backup\temp。难道没有自动为其提供第一个遇到的文件夹的方法。Temp只是一个示例,它会改变…@oJM86o您必须决定规则。我不知道您的要求。如果用户选择了c:\Program Files\SomeApp,那么输出应该是c:\backup\SomeApp还是c:\backup\Program Files\SomeApp?我正在演示复制文件的修复方法您遇到的问题,我没有试图为您提供完整的解决方案。在这种情况下,可能是
    c:\backup\Program Files\SomeApp
    这就是我的问题所在。