【问题标题】:How to copy efficiently UNC paths in the same remote machine如何在同一台远程机器上有效地复制 UNC 路径
【发布时间】:2016-10-18 11:19:57
【问题描述】:

我正在研究一种在同一台远程机器上复制大文件的有效解决方案,我们称之为 FILESERVER。然后,从另一台服务器(WEBSERVER)我想远程发布这些文件的副本,所以我尝试使用 Windows 资源管理器将文件复制/粘贴到同一个远程共享文件夹中,我注意到它不需要通过移动文件内容网络,所以我认为使用共享文件夹并简单地从 WEBSERVER 复制文件就可以了。

所以,我用下面的代码试了一下。

File.Copy("\\FILESERVER\FOLDER\bigfile", "\\FILESERVER\FOLDER2\bigfile");

这可行,但我注意到它实际上是通过网络移动文件内容,而这正是我想要避免的。我不想在 FILESERVER 中实现一个服务器来接收复制文件的命令,如果我可以使用内置的 Windows 机制来做到这一点。所以我想实现的行为与 Explorer 相同,从我的 c# 代码中调用它。那么,可以在 .NET 中执行此操作吗?

编辑: 我尝试了 XCOPY 命令,起初它似乎没有使用网络。 但是在重新启动以确保它不涉及任何操作系统缓存之后,我注意到当我从 cmd 执行 XCOPY 时,它不会在 Process Explorer/taskmgr 中显示任何 I/O,但是,当我从我的 C# 代码执行此命令时确实如此。所以我认为它确实使用网络来获取/写入文件内容,但出于一个奇怪的原因,这些诊断工具(taskmgr / Process Explorer)中没有报告它。

【问题讨论】:

  • 这可能与老式的 shell 对象有关 - 请参阅 msdn.microsoft.com/en-us/library/windows/desktop/…(没有 C# 示例,但它可能会让您入门)。它具有不显示标准 Windows Explorer 复制对话框的标志,因此它似乎应该与 Windows Explorer 使用的 API 相同。
  • 试试它是否适用于命令行中的 COPY 命令。如果是这样,请使用 proc = new ProcessStartInfo("cmd", "/c COPY \\FILESERVER\FOLDER\bigfile \\FILESERVER\FOLDER2\bigfile"); ... proc.Start(); 运行它
  • 好吧,我必须再次尝试 XCOPY,但我注意到它也会通过网络移动内容。我确实评论说它有效,但我必须再试一次。

标签: c# .net wmi unc


【解决方案1】:

使用 PSEXEC 并在远程计算机上使用本地文件夹路径运行副本。

【讨论】:

  • 这似乎是一个不错的方法,PSEXEC 是自治的,并且会自动在另一台机器上安装服务。但是,我宁愿从没有任何外部实用程序的代码中完成它。我希望有人知道 API 可以做到这一点(如果存在)。
  • 只有在本地运行时才会在本地运行。从另一台机器它总是会使用网络,因为命令必须“管理”数据。
  • 我一开始也是这么想的,但是我已经将文件复制到同一个共享文件夹中,并且 taskmgr 显示的网络活动很少。就像它使用某种“API”让 Windows 知道可以在远程硬盘驱动器中完成复制。
  • 您可以使用 WMI 在远程机器上执行 xcopy,但是如果没有 - 即使是很小的 - 网络流量,就没有机会进行复制。
  • 当然,我要防止的是从远程机器移动 1 GB 到客户端机器,然后将该 GB 写回远程机器,所有这些都使用网络。简单地复制同一硬盘中的文件,将正确的命令发送到远程机器,效率要高得多。我还更新了这个问题,因为似乎 XCOPY 和 Explorer 可能也在使用网络,但由于奇怪的原因它在 taskmgr 中不可见......
【解决方案2】:

WMI 无疑是一个很好的方法。我终于设法用下面的代码和 CopyEx 方法递归地复制目录。

var classInstance = new ManagementObject("\\\\FILESERVER\\root\\cimv2", "Win32_Directory.Name='c:\\path\\to\\directory1'", null);

var copyExInParams = classInstance.GetMethodParameters("CopyEx");

// Add the input parameters.
copyExInParams["FileName"] = "c:\\path\\to\\directory2";
copyExInParams["Recursive"] = true;
copyExInParams["StartFileName"] = null;

var copyExOutParams = classInstance.InvokeMethod("CopyEx", copyExInParams, null);

请务必注意,路径必须采用远程机器格式。我无法证明这一点,但也许 Windows 资源管理器正在利用 WMI 将文件复制到共享文件夹中的同一台远程计算机中,以防止无用的网络流量。我还没有找到直接使用 UNC 的方法。即使这适合我的用例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多