【问题标题】:How to prevent recursive in copying files and dirs?如何防止递归复制文件和目录?
【发布时间】:2021-01-19 19:11:59
【问题描述】:

我遇到了复制文件/目录的问题。几乎整天都在挣扎。 我必须从根目录文件及其带有文件和子目录的目录复制。 事实上,我已经做了一些事情。但是,每次我运行时都会出现stackoverflow错误。

abstract class SystemOperations {
    public virtual void SearchFiles() { }
    public virtual void SearchDirectories() { }

    public abstract void CreateDirectory(string DIR);
    public abstract void CloneContent(string DIR);
    public abstract void CreateJSON(string DIR);

    public void ExecuteCopying(string DIR) {
        CreateDirectory(DIR);
        CloneContent(DIR);
        CreateJSON(DIR);
    }
}

class FileOperations : SystemOperations {
    DirectoryInfo _MainPath;
    public DirectoryInfo MainPath {
        get { return _MainPath; }
        set { _MainPath = value; }
    }

    public FileOperations(DirectoryInfo MainPath) {
        this.MainPath = MainPath;
    }

    #region Unnecessary for current task
    public override void SearchFiles() {
        string path = "";
        FileInfo[] files = MainPath.GetFiles();

        foreach (FileInfo file in files) {
            path = file.Name;
        }
    }

    public override void SearchDirectories() {
        string path = "";
        DirectoryInfo[] directories = MainPath.GetDirectories();

        foreach (DirectoryInfo directory in directories) {
            path = directory.Name;
        }
    }
    #endregion

    public override void CreateDirectory(string DIR) {
        string newFolder = Path.Combine(MainPath + "", DIR);
        Directory.CreateDirectory(newFolder);
    }

    public override void CloneContent(string DIR) {

        foreach (var directory in Directory.GetDirectories(MainPath + "")) {
            string dir = Path.GetFileName(directory);

            CloneContent(Path.Combine(MainPath + "", dir));
        }

        foreach (var file in Directory.GetFiles(MainPath + "")) {
            File.Copy(file, Path.Combine(MainPath + "", Path.GetFileName(file)), true);
        }
    }

    public override void CreateJSON(string DIR) {
        if (!Directory.Exists(DIR)) {
            var asd = new DirectoryInfo(DIR);
        }
    }
}

class Program {
    static void Main() {
        SystemOperations task = new FileOperations(new DirectoryInfo(@"D:\\LAK"));
        task.ExecuteCopying("COPY");
    }
}

因此,函数 CloneContent 必须复制到每个 dir/subdirs 文件中。但是它的递归函数,正如我上面写的,我遇到了错误。而且不知道如何解决这个问题。谢谢你!

【问题讨论】:

  • 当使用递归时,你需要一个 break out 子句。必须有一个你不递归的场景。这是一个示例:geeksforgeeks.org/program-for-nth-fibonacci-number。在这种情况下,如果输入的值小于 2,则退出函数。
  • foreach (var directory in Directory.GetDirectories(MainPath + "")) 应该是 ...GetDirectories(DIR))
  • 你的 Search... 函数没有意义,它们什么都不做。 MainPath + ""MainPath 相同。 _mainPath 也可以通过使其成为自动属性来删除。
  • @Charlieface 不,MainPath + ""MainPath.ToString() 相同(MainPathDirectoryInfo 实例)。但是应该注意the documentation 声明应该使用FullName 属性。
  • @Charlieface MainPath 不是字符串。这是一个DirectoryInfo 对象。如果你要做Directory.GetDirectories(MainPath),你会得到一个编译错误。你需要做Directory.GetDirectories(MainPath.FullName)Directory.GetDirectories(MainPath.ToString()) 或像他们那样做Directory.GetDirectories(MainPath + "")。更好的是,因为它是一个 DirectoryInfo 对象:MainPath.GetDirectories()

标签: c# system.io.file


【解决方案1】:

您尝试确定接下来需要搜索哪个目录的方式存在某种问题,我认为使用 MainPath 是错误的。

就我个人而言,我也总是更喜欢使用辅助停止条件来避免 StackOverflowException,例如我在下面使用的 maxrunCount。

如果您想要递归目录查找,您应该将代码重写为类似

void Main()
{
    string MainPath = "D:\\LAK";
    // unless your directory is actually named \LAK:) you should use either @"D:\LAK" or "d:\\LAK"
    CloneContent(MainPath,1000);
}

public void CloneContent(string directoryToSearch, int maxrunCount)
{
    if(maxrunCount==0)
        return;
        
    System.Diagnostics.Debug.Print(directoryToSearch);
    string[] directories = null;
    try
    {
        directories = Directory.GetDirectories(directoryToSearch);
    }
    catch(UnauthorizedAccessException ex) {
        System.Diagnostics.Debug.Print($"No access to dir {directoryToSearch}");
        directories = new string[0];
    }
    
    // ensure you have access to the current directoryToSearch
    foreach (var directory in directories)
    {
        CloneContent(directory,--maxrunCount);
    }
    System.Diagnostics.Debug.Print($"cloning {directoryToSearch}");
    // .... do the actual cloning here, 
    // you will end up here when there are no more subdirectories on the current branch
}

【讨论】:

    【解决方案2】:

    要使递归方法起作用,它必须至少具有一个“退出”条件——它完成工作并可以展开堆栈的点。在我们的例子中,就是没有更多的目录或文件可以从源复制到目标。

    编写此方法的一种方法是获取源目录和目标目录,然后它可以递归地为每个子目录调用自己:

    public static void CloneContent(string sourceDir, string destDir)
    {
        // If the source directory doesn't exist, return
        if (!Directory.Exists(sourceDir)) return;
        
        // Create destination if needed
        Directory.CreateDirectory(destDir);
    
        // Copy files from this directory to the new path
        foreach (string file in Directory.GetFiles(sourceDir))
        {
            File.Copy(file, Path.Combine(destDir, Path.GetFileName(file)));
        }
    
        // Recursively call this method for each sub directory
        foreach (string subDir in Directory.GetDirectories(sourceDir))
        {
            string dirName = Path.GetFileName(subDir);
            string newSource = Path.Combine(sourceDir, dirName);
            string newDest = Path.Combine(destDir, dirName);
    
            CloneContent(newSource, newDest);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-24
      • 1970-01-01
      • 1970-01-01
      • 2010-12-31
      • 1970-01-01
      • 2021-06-28
      • 2010-11-16
      • 2019-09-18
      相关资源
      最近更新 更多