【问题标题】:recursion? Or how to keep getting parents parent?递归?或者如何让父母成为父母?
【发布时间】:2013-01-16 03:20:21
【问题描述】:

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

  1. 从哪里复制(txtPath)
  2. 要复制的文件扩展名(您指定的是要复制的文件扩展名)(txtExtensions)
  3. 复制到哪里(txtArchiveTo)

视觉上是这样的:

从 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 链接,我已阅读并理解它们。

【问题讨论】:

  • @DJKRAZE 这不是我的问题...我知道如何递归地复制文件。问题是如何维护正确的路径,因为我第一次获取文件..然后如果出现一个目录,它会回忆 WalkDirectoryTree,这就是它可能变得时髦的地方,因为该目录需要与 txtPath 处于同一级别......跨度>
  • 当前路径应该保存在一个变量中。现在,如果您在当前目录中,您应该将基于该扩展名的文件保存到数组或列表中,并在 foreach 中迭代该列表在那个循环中循环然后你做副本这有意义吗..?
  • ispiro - 我的问题是如何进行复制...因为只要我点击一个新目录和“WalkDirectoryTree()”我就有了一个新的根...基本上是副本应该匹配但进入一个新位置,查看我现有的代码,我可以在那里做些什么来修复它...
  • 发布Directory.Exists(txtArchiveTo.Text + "\\" + fi.Directory.Name运行结果的字符串值用一个小例子。通过这种方式,我们了解您的代码是如何工作的,然后发布您真正想要的内容。我应该指出你的最后一段毫无意义。

标签: c# winforms recursion


【解决方案1】:

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

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

【讨论】:

  • 这样的工作......但把这个结构c:\temp\test1想象成txtPath。 txtArchive 包含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 这是我的问题所在。
猜你喜欢
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2020-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多