文章目录
- refs
- 常见复制工具
- 高速拷贝工具
- 特性对比
- Robocopy👺
- Robocopy工具
- 基本用法
- 语法
- 示例
- 常用选项
- 常见选项列表
- 示例
- 高级用法
- 多线程复制
- 日志记录
- 用例案例
- 直接递归复制大量文件的文件夹
- 多线程复制
- 监视被打开文件文件数
- 复制时排除某个目录
- 排除交接点@跳过无法复制的项目@拒绝访问时跳过
- 跳过报错
- powershell封装robocopy👺
- Copy-Robocopy
- Get-PsIoItemInfo
- FAQ
- 复制指定文件时指定正确的参数
- 复制单个文件
- 不兼容传统的copy用法
- 默认作为目录处理
- 从目录A复制到目录B时不会保留目录A
- 递归复制和指定复制的冲突
- 综合示例
- robocopy 复制符号链接和硬链接问题👺
refs
- Windows中常用文件拷贝工具的评测和对比-阿里云开发者社区 (aliyun.com)
- 如何使用Robocopy多线程功能加速Windows 中的文件复制 - 系统极客 (sysgeek.cn)
- SMB 文件服务器的性能优化 | Microsoft Learn
常见复制工具
高速拷贝工具
推荐Robocopy,Rclone
- Robocopy | Microsoft Learn
- GitHub - rclone/rclone: “rsync for cloud storage” - Google Drive, S3, Dropbox, Backblaze B2, One Drive, Swift, Hubic, Wasabi, Google Cloud Storage, Azure Blob, Azure Files, Yandex Files
特性对比
- 表格内容可能会过时,部分特性随着软件更新发生变换
- 表格中我仅使用过前几款,后面的为验证
工具名称 | 多线程支持 | 价格 | 跨平台性 | 易用性 | 断点续传 | 文件校验 | 是否有图形界面 | 备注 |
Windows 资源管理器 | 否 | 免费 | 仅限Windows | 非常易用 | 否 | 否 | 是 | 系统自带,适合简单文件复制 |
Robocopy | 是 | 免费 | 仅限Windows | 中等 | 是 | 是 | 否 | 命令行工具,适合高级用户 |
Rclone | 是 | 免费 | 跨平台(Win, Mac, Linux) | 中等 | 是 | 是 | 否 | 强大的命令行工具,支持多种云存储 |
FastCopy | 是 | 免费 | Windows, Linux | 中等 | 是 | 是 | 是 | 提供GUI和命令行界面,速度快 |
TeraCopy | 是 | 免费/付费版 | 仅限Windows | 易用 | 是 | 是 | 是 | 提供GUI界面,付费版功能更多 |
FreeFileSync | 是 | 免费 | 跨平台(Win, Mac, Linux) | 中等 | 是 | 是 | 是 | 同步功能强大 |
rsync | 是 | 免费 | 跨平台(Win*, Mac, Linux) | 中等 | 是 | 是 | 否 | 需通过Cygwin等在Windows上使用 |
SyncBack | 是 | 免费/付费版 | 仅限Windows | 易用 | 是 | 是 | 是 | 界面友好,适合备份和同步任务 |
Beyond Compare | 是 | 付费 | 跨平台(Win, Mac, Linux) | 易用 | 是 | 是 | 是 | 强大的比较和同步功能 |
Robocopy👺
- 简单使用演示:备份杀手锏robocopy使用秘籍——程序员小Tips第一期_哔哩哔哩_bilibili
- 最重要的特性莫过于多线程复制了,如果您仅对快速复制和多线程复制特性感兴趣,跳转到powershell封装一节,直接使用封装后的命令,和powershell自带的copy同样直观和易用
Robocopy工具
Robocopy(Robust File Copy)是Windows的一个命令行工具,用于高效地复制、移动和同步文件和目录。与传统的复制命令相比,Robocopy具有更强大的功能和更高的灵活性。
- 可指定多线程复制
- 镜像备份功能(可能会删除文件)
- 可以指定复制软链接是如何处理
- 提供了移动选项,可以用作移动工具
- 控制IO速率
- 复制文件属性,访问控制权限等信息
于此同时,Robocopy的部分选项有删除的效果,因此要小心使用(比如/Mir
镜像功能,可以用于备份,但不推荐多人使用)
以下仅介绍核心用法
基本用法
语法
- Source:源目录路径。
- Destination:目标目录路径。
- File:要复制的文件,可以使用通配符(例如
*.*
)。 - Options:可选参数,用于控制复制行为。
参数 | 描述 |
| 指定源目录的路径。 |
| 指定目标目录的路径。 |
| 指定要复制的一个或多个文件。 支持通配符(***** 或 ?)。 如果未指定此参数, |
| 指定要与 robocopy 命令结合使用的选项,包括复制、文件、重试、日志记录和作业选项。 |
示例
- 文件夹的基本复制
将C:\Source
目录中的所有文件(但不包括子目录及其文件,也就是默认跳过对子目录的处理)复制到D:\Destination
目录(这种用法比较少,一般用普通的copy命令就行)
如果要一同处理子目录,那么需要使用/E
选项,类似于启用递归复制的效果(Copy-Item -Reverse
)
- 复制特定文件类型
只复制C:\Source
目录中的.txt
文件到D:\Destination
目录:
这可以指定复制特定文件,但是要注意避免和/E
等选项冲突
常用选项
常见选项列表
选项 | 说明 |
| 复制子目录,但不包括空的子目录 |
| 复制所有子目录,包括空的子目录 |
| 镜像目录树(等同于 |
| 复制文件的数据、时间戳、权限等,默认值为 |
| 移动文件(复制后删除源文件) |
| 移动文件和目录(复制后删除源目录和文件) |
| 出错重试次数,默认值为1,000,000次 |
| 每次重试等待时间(秒),默认值为30秒 |
| 将输出结果记录到指定的日志文件 |
| 不显示复制进度百分比 |
示例
- 复制目录结构
复制C:\Source
目录及其所有子目录(包括空的子目录)到D:\Destination
:
- 镜像同步
将C:\Source
目录镜像同步到D:\Destination
,使目标目录与源目录完全一致:
- 移动文件
将C:\Source
目录中的所有文件和目录移动到D:\Destination
:
高级用法
多线程复制
使用 /MT
选项可以启用多线程复制,提高复制速度。可以指定线程数(最大为128):
日志记录
使用 /LOG
选项将复制结果记录到日志文件,便于后续分析:
用例案例
直接递归复制大量文件的文件夹
平均速度大约是2.78MB/s
,总共复制了60.16m字节的数据
开始时间和介绍时间分别为12:45:13
,12:46:02
,差值为49秒
多线程复制
其他条件基本相同的情况下(下面的例子是几个小时后测试的),和上面的例子一样,复制同一个文件夹
现在使用/MT
多线程选项,并结合日志控制和重定向,来看看会不会有更快的速度
- 可以追加跟踪
cat C:\temp\rbcopy_log.txt -wait
由于这个文件夹存在2个快捷方式权限特殊,复制过程中遇到了属性错误,但是不影响总体的复制效果
平均速度大约是16.9MB/s
,总共复制了60.16m字节的数据
开始时间和介绍时间分别为15:15:06
,15:15:10
,差值为4秒
可以看到,robocopy启用多线程复制众多小文件的速度十分的快速(本次试验中,效果相比于默认的单线程速度有了一个数量级左右的提高)
监视被打开文件文件数
上面的试验是我利用虚拟机,通过挂载局域网内的smb共享文件夹复制一个git仓库的试验
在使用/MT:16
多线程选项复制过程中,我趁机在smb服务器端使用Get-smbSession
查看到了某个瞬间有462个资源处于操作状态状态
复制时排除某个目录
例如复制一个git仓库,排除.git
目录
排除交接点@跳过无法复制的项目@拒绝访问时跳过
复制选项 | 说明 |
/sj | 将交接点(软链接)复制到目标路径而不是链接目标。 |
/sl | 不是接在符号链接的后面,而是创建链接的副本。 |
文件选项(交接点排除) | 说明 |
/xj | 排除交接点(通常默认会包含)。 |
/xjd | 排除目录的交接点。 |
/xjf | 排除文件的交接点。 |
跳过报错
- 使用
/R:0
选项即可(直接跳过报错部分)
powershell封装robocopy👺
- 帮助用户更加容易的使用robocopy的核心功能(多线程复制和递归复制),作为常规copy命令的一个补充
- 而简单的单文件复制一般用普通的copy命令就足够方便快捷了
Copy-Robocopy
- 下面这个函数需要调用辅助函数
Get-PsIoItemInfo
Get-PsIoItemInfo
- 上面的
Copy-Robocopy
调用到了这个辅助函数
FAQ
复制指定文件时指定正确的参数
复制单个文件
可以看到任务开始时间和结束时间,它们做差是3秒钟
不兼容传统的copy用法
- 对于传统的copy用法(比如powershell中的copy命令,复制特定文件的语法不同,直接在source处指定源文件而非源文件夹会出错,同样的,在destination处直接指定复制后的文件名也会出错)
默认作为目录处理
- 从下面的错误示例可以看出,source,destination位置处的参数被当成文件夹来处理而不是识别为文件
从目录A复制到目录B时不会保留目录A
- 和powershell自带的
copy
命令不同,使用robocopy A B
复制时(使用递归复制/E
),会将A
目录中的文件和子目录复制到B
中,也就是说A
中的文件或子目录直接挂在B
下面
- 举例来说,
A
目录下有个a.txt
文件,那么经过上述复制,目录B
中会有a.txt
,但是不会隔着一层A
目录
- 这种行为有时会造成困扰,例如目录A是某个便携版软件的目录,B目录中有很多其他文件和子目录,如果用上面的方法复制,那么目录B中其他文件会和目录A中的文件混在一起,导致目录B内的结构发生混乱难以维护且容易造成冲突!
- 如果要保留复制到B目录中的A目录层级,可以改为
robocopy A B\A
,这样目录A复制到B中时,新文件就会挂在B\A
目录下
递归复制和指定复制的冲突
- 如果要复制指定文件,那么不要使用
/S,/E
这类选项,会冲掉指定的文件,而仍然执行递归复制
您在命令中使用了 /E
选项,这会导致 Robocopy 复制源目录 X:\exes\
下的所有子目录和文件,而不仅仅是指定的 pwsh7.4.4.msi
文件。
为了仅复制 pwsh7.4.4.msi
文件,不要使用 /E
选项。下面是修正后的命令:
这样就只会复制指定的文件 pwsh7.4.4.msi
,而不会包括子目录。
完整命令的解释:
-
X:\exes\
是源目录。 -
C:\exes\
是目标目录。 -
pwsh7.4.4.msi
是要复制的文件。 -
/ETA
显示估计完成时间。
如果您需要记录日志或其他选项,可以添加相应的选项。例如:
此命令将 pwsh7.4.4.msi
文件从 X:\exes\
目录复制到 C:\exes\
目录,并将输出记录到日志文件中,同时不显示进度百分比。
综合示例
以下是一个综合示例,将以上改进和查看进度的方法结合起来:
-
/E
:复制所有子目录,包括空的子目录。 -
/NP
:不显示进度百分比。 /LOG:C:\temp\rbcopy_log.txt
:将输出记录到日志文件(有可能缺少权限而无法写入)。
- 可以选择
-
/NFL
和/NDL
:禁用文件和目录列表的输出。 -
/ZB
: -
/ETA
:显示估计完成时间。 -
/MT:16
:启用16个线程进行多线程复制。
这种配置可以最大限度地减少终端输出,记录详细的日志,并且显示估计完成时间,同时提高复制速度。
robocopy 复制符号链接和硬链接问题👺
- 如果你了解并会在windows上创建硬链接或符号链接或链接点,在使用robocopy复制的文件夹内包含相关符号时可能会出现符号定位错误
- 例如,我使用windows的SMB共享文件夹功能,将目录
C:\share
做了共享设置,在另一台设备上可以访问该共享文件夹,并将其挂载为网络驱动器(比如盘符为X:
),可用net use X: \\server\shareName
来挂载 - 假设
C:\share
目录中有一个文件Fhard.txt
是C:\share
之外的目录的某个文件F.txt
的硬链接,使用robocopy直接复制就会出错 - 比如通过以下powershell命令行
- 可能的原因分析:
- 由于这里是通过SMB客户机(简称为SMB client或client)上挂载共享文件为网络驱动器盘符
X:
,能够看到的文件范围局限于SMB服务端(简称SMB server或server)的C:\share
目录下的内容(而server的C:
目录下的非share
子目录是无法被client所访问) - 也就造成了如果server端中的C:\share目录包含了其他目录的文件的硬链接,那么使用robocopy复制这类"文件"(符号)时,会由于链接(符号)所指的文件位于其他不可被client所访问的目录下,就会造成错误
- 而引起robocopy错误的硬链接是这样被创建出来的:
- 假设被复制的文件夹中包含了一个硬链接,这会导致默认的robocopy复制出错
- 如果硬链接的源头是client可以访问的目录,那么robocopy复制它时就不会报错
顺利复制: