【问题标题】:C# Directory copying returns no error, but does not copy directoryC# 目录复制不返回错误,但不复制目录
【发布时间】:2018-02-06 00:39:28
【问题描述】:

我正在编写一个非常小的应用程序来将目录从一个地方复制到另一个地方,并增加了一些自动化。除了实际的复制方法外,整个应用程序都可以完美运行。最糟糕的是,我根本没有收到任何错误,而且正如你们大多数人所知,这比收到错误要糟糕得多。

这里是有问题的方法:

public static bool CopyDir(string sPath, string dPath)
        {
            string[] files = Directory.GetFiles(sPath);
            try
            {
                foreach (string file in files)
                {
                    string name = Path.GetFileName(file);

                    foreach (string dirPath in Directory.GetDirectories(sPath, "*",
                        SearchOption.AllDirectories))
                        Directory.CreateDirectory(dirPath.Replace(sPath, dPath));

                    foreach (string newPath in Directory.GetFiles(sPath, "*.*",
                        SearchOption.AllDirectories))
                        File.Copy(newPath, newPath.Replace(sPath, dPath), true);
                }
            } catch // this is no use because the Exception is empty.
            {
                return false;
            }
            return false; //the app keeps executing to here and I don't know why
        }

来自调试器的变量转储:

  • sPath:"C:\\Users\\Jacob Jewett\\Downloads\\func1"
  • dPath:"C:\\Users\\Jacob Jewett\\AppData\\Roaming\\.minecraft\\saves\\data\\functions\\"
  • 文件:[0]"C:\\Users\\Jacob Jewett\\Downloads\\func1\\main.mcfunction"

Downloads\func1(sPath)的文件夹树:

func1
  main.mcfunction

编辑(下午 2:33):好的,这是我重构的代码,它返回 File in use 错误但不复制任何内容。

   public static bool CopyDir(string sPath, string dPath)
        {
            try
            {
                foreach (string dirPath in Directory.GetDirectories(sPath, "*",
                    SearchOption.AllDirectories))
                    Directory.CreateDirectory(dirPath.Replace(sPath, dPath));

                foreach (string newPath in Directory.GetFiles(dPath, "*.*",
                    SearchOption.AllDirectories))
                    File.Copy(newPath, newPath.Replace(sPath, dPath), true);
                return true;
            }
            catch (UnauthorizedAccessException e)
            {
                MessageBox.Show("Attempt to copy failed. Raw: "+e,"IO Error",MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }

编辑(8-29-17 12:09PM):我已经对方法进行了一些调整,现在我得到了一个Access to path [path] is Denied.,这更好总比没有,但我还没有遇到一个可行的解决方案。我在这里浏览了一些错误,大多数人说在调用File.Copy() 方法之前放置File.SetAttributes()。这没有效果。或者,我尝试在完成任何复制之前将sPath1 的属性Read-Only 目录设置为none,这也没有效果。

当前代码:

public static bool CopyDir(string sPath, string dPath)
{
    try
    {
        DirectoryInfo spdi = new DirectoryInfo(sPath);
        spdi.Attributes &= ~FileAttributes.ReadOnly;
        foreach (string dirPath in Directory.GetDirectories(sPath, "*",
            SearchOption.AllDirectories))
            Directory.CreateDirectory(dirPath);

        foreach (string newPath in Directory.GetFiles(dPath, "*.*",
            SearchOption.AllDirectories))
        { 
            File.SetAttributes(dPath, FileAttributes.Normal);
            File.Copy(sPath, newPath);
        }
        Directory.CreateDirectory(dPath);
        return true;
    }
    catch (UnauthorizedAccessException e)
    {
        MessageBox.Show("Attempt to copy failed. (UAC) Raw: "+e,"IO Error",MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
    }
}

【问题讨论】:

  • 它很可能在catch 块内命中return false。你遇到了一个异常,但它只是被吞没了,你永远看不到错误。
  • 我确实尝试添加一个更好的 catch 块,但异常什么也不返回。从我所见,它甚至都没有到达 catch 块。
  • 您是否尝试过使用调试器单步执行?
  • 除了断点之外,还没有真正接触过调试器,我想如何调试以及要调试什么?
  • 在 catch 块中的return false 上放置一个断点。

标签: c# directory copy system


【解决方案1】:

编辑:我重新阅读了您的代码,我认为我遇到了真正的问题。

以下说明足以将所有子目录和文件复制到目标位置。

foreach (string dirPath in Directory.GetDirectories(sPath, "*",
         SearchOption.AllDirectories))
         Directory.CreateDirectory(dirPath.Replace(sPath, dPath));

foreach (string newPath in Directory.GetFiles(sPath, "*.*",
        SearchOption.AllDirectories))
        File.Copy(newPath, newPath.Replace(sPath, dPath), true);

外部的 foreach 是多余的。

这里是更正的代码:

public static bool CopyDir(string sPath, string dPath)
{
    try
    {
         foreach (string dirPath in Directory.GetDirectories(sPath, "*",
                SearchOption.AllDirectories))
                Directory.CreateDirectory(dirPath.Replace(sPath, dPath));

         foreach (string newPath in Directory.GetFiles(sPath, "*.*",
                SearchOption.AllDirectories))
                File.Copy(newPath, newPath.Replace(sPath, dPath), true);
    }
    catch // this is no use because the Exception is empty.
    {
        return false;
    }

    return false; //the app keeps executing to here and I don't know why
}

也就是说,在 catch 块中使用 Exception 执行某些操作是一个好习惯。即使它只是记录它:) 这样你就可以排除它,如果它没有记录。

【讨论】:

  • string[] files 不是空的。调试器显示它包含源目录main.mcfunction 中的所有正确文件。
  • 对,我的错:S 编辑了我的答案以删除该假设。然而,代码仍然适用于我,所以它必须是别的东西。 sPath 的文件夹结构是什么样的?
【解决方案2】:

当您说没有错误时,文件是否复制?如果是这样,那么您可能只是忘记在 try 块的外部 foreach 循环结束时返回 true。

否则这段代码对我来说完美地复制了一个文件夹结构。

try{
    foreach(...)
    {
       // etc
    }

    return true;     // <<<<<<--------
}
catch
{
}
return false;

另外,如果您在主 GUI 线程中运行它,那么它会锁定一些东西,并且调试器可能会抱怨上下文切换死锁,因此请确保您在线程中运行它。

在使用调试器方面,在要停止的地方放置一个断点,然后使用 F10 跨行,F11 跨行。

【讨论】:

    猜你喜欢
    • 2013-12-16
    • 2016-12-02
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多