如何强制Robocopy覆盖文件?

46

一般来说,Robocopy会忽略最后修改日期和文件大小相同的文件。那么我们如何避免这种设计呢?我想用Robocopy强制覆盖文件。

我希望dst\sample.txt被写作test001。但是Robocopy将这些文件识别为相同的文件并且不进行覆盖。在这种情况下,“/IS”选项无效。

New-Item src -itemType Directory
New-Item dst -itemType Directory
New-Item src\sample.txt -itemType File -Value "test001"
New-Item dst\sample.txt -itemType File -Value "test002"
Set-ItemProperty src\sample.txt -Name LastWriteTime -Value "2016/1/1 15:00:00"
Set-ItemProperty dst\sample.txt -Name LastWriteTime -Value "2016/1/1 15:00:00"

ROBOCOPY.exe src dst /COPYALL /MIR
Get-Content src\sample.txt, dst\sample.txt
> test001
> test002

ROBOCOPY.exe src dst /COPYALL /MIR /IS
Get-Content src\sample.txt, dst\sample.txt
> test001
> test002
4个回答

41

文档中得知:

/is 包含相同的文件。 /it 包含“调整过”的文件。

“相同的文件”是指文件名称、大小、时间和属性都相同。“调整过的文件”是指文件名称、大小和时间相同,但属性不同的文件。

robocopy src dst sample.txt /is      # copy if attributes are equal
robocopy src dst sample.txt /it      # copy if attributes differ
robocopy src dst sample.txt /is /it  # copy irrespective of attributes

这个回答在超级用户上很好地解释了选择参数匹配哪种类型的文件。

话虽如此,我可以重现您描述的行为,但根据文档和输出robocopy在我的测试中生成的情况,我认为这是一个错误。

PS C:\temp> New-Item src -Type Directory >$null
PS C:\temp> New-Item dst -Type Directory >$null
PS C:\temp> New-Item src\sample.txt -Type File -Value "test001" >$null
PS C:\temp> New-Item dst\sample.txt -Type File -Value "test002" >$null
PS C:\temp> Set-ItemProperty src\sample.txt -Name LastWriteTime -Value "2016/1/1 15:00:00"
PS C:\temp> Set-ItemProperty dst\sample.txt -Name LastWriteTime -Value "2016/1/1 15:00:00"
PS C:\temp> robocopy src dst sample.txt /is /it /copyall /mir
...
  Options : /S /E /COPYALL /PURGE /MIR /IS /IT /R:1000000 /W:30
------------------------------------------------------------------------------
1 C:\temp\src\ Modified 7 sample.txt ------------------------------------------------------------------------------
Total Copied Skipped Mismatch FAILED Extras Dirs : 1 0 0 0 0 0 Files : 1 1 0 0 0 0 Bytes : 7 7 0 0 0 0 ... PS C:\temp> robocopy src dst sample.txt /is /it /copyall /mir ... Options : /S /E /COPYALL /PURGE /MIR /IS /IT /R:1000000 /W:30
------------------------------------------------------------------------------
1 C:\temp\src\ Same 7 sample.txt ------------------------------------------------------------------------------
Total Copied Skipped Mismatch FAILED Extras Dirs : 1 0 0 0 0 0 Files : 1 1 0 0 0 0 Bytes : 7 7 0 0 0 0 ... PS C:\temp> Get-Content .\src\sample.txt test001 PS C:\temp> Get-Content .\dst\sample.txt test002

文件被列为已复制,由于在第一次robocopy运行后它变成了相同的文件,因此至少时间被同步了。但是,尽管根据输出已经复制了七个字节,但在这两种情况下实际上都没有将数据写入到目标文件中,尽管设置了数据标志(通过/copyall)。如果明确设置数据标志(/copy:d),行为也不会改变。

我必须修改最后的写入时间才能让robocopy实际上同步数据。

PS C:\temp> Set-ItemProperty src\sample.txt -Name LastWriteTime -Value (Get-Date)
PS C:\temp> robocopy src dst sample.txt /is /it /copyall /mir
...
  Options : /S /E /COPYALL /PURGE /MIR /IS /IT /R:100
& robocopy src dst /is /it /l /ndl /njh /njs /ns /nc |
  Where-Object { $_.Trim() } |
  ForEach-Object {
    $f = Get-Item $_
    $f.LastWriteTime = $f.LastWriteTime.AddSeconds(1)
  }
& robocopy src dst /copyall /mir

转换到xcopy可能是您最好的选择:

& xcopy src dst /k/r/e/i/s/c/h/f/o/x/y

1
好的。我将使用xcopy。 - tbl
我同意并且三年后,/is开关似乎不能强制文件再次复制。它显示已复制(即copy = 1),但显然没有复制,因为我使用1GB进行测试,而且复制瞬间完成。 - Rob Nicholson
刚在 Windows Server 2019 上尝试了一下,使用 robocopy source destn file /is 命令确实会再次复制文件。该系统的版本是 v10.0.17763,与 Windows 10 1809 版本相同。 - Rob Nicholson
1
Windows Server 2019的Robocopy 10.0.17763.1从本地到本地,按预期覆盖文件。同样的命令从本地到映射的网络驱动器,覆盖不会发生。我怀疑DFS(分布式文件系统)。从本地到映射网络驱动器的UNC相同命令,覆盖不起作用。从本地到另一台开发计算机的UNC相同命令,覆盖按预期工作。我确保共享缓存已打开并再次尝试,覆盖工作了。因此,我认为DFS是问题所在或需要使用/ZB。 - AMissico
对我有用 :) - Naveen Kumar V

34

这真的很奇怪,为什么没有人提到/IM开关?!我在备份工作中长期使用它。但是我刚刚尝试搜索,甚至在微软网站上也找不到任何有关它的信息!!! 同样发现了许多用户帖子抱怨同样的问题!!

无论如何...要使用Robocopy覆盖源和目标中的 所有 文件,无论大小或时间,您必须在命令中包括这三个开关(/IS /IT /IM)。

/IS :: Include Same files. (Includes same size files)
/IT :: Include Tweaked files. (Includes same files with different Attributes)
/IM :: Include Modified files (Includes same files with different times).

这是我用来传输几千兆字节大多数为1GB+的文件(ISO - 磁盘映像 - 4K 视频)的确切命令:

robocopy B:\Source D:\Destination /E /J /COPYALL /MT:1 /DCOPY:DATE /IS /IT /IM /X /V /NP /LOG:A:\ROBOCOPY.LOG

我为您做了一个小测试... 这是结果:

               Total    Copied   Skipped  Mismatch    FAILED    Extras
    Dirs :      1028      1028         0         0         0       169
   Files :      8053      8053         0         0         0         1
   Bytes : 649.666 g 649.666 g         0         0         0   1.707 g
   Times :   2:46:53   0:41:43                       0:00:00   0:41:44


   Speed :           278653398 Bytes/sec.
   Speed :           15944.675 MegaBytes/min.
   Ended : Friday, August 21, 2020 7:34:33 AM

目标磁盘: WD Gold 6TB (将写入速度与我的结果进行比较)

即使有那些“额外”的内容,那也只是因为开启了“/X”选项而进行报告。正如您所看到的,没有跳过任何文件,并且所有文件的总数和大小都等于已复制的数量和大小。有时,当我在操作期间多次滥用它并取消它时,它会显示少量跳过的文件,但即使如此,前两列中的值始终相等。我以前也通过运行一段 PowerShell 脚本来验证过这一点,该脚本扫描目标中的所有文件并生成所有时间戳的报告。

我在处理它并经历了很多测试和麻烦之后,得出了一些性能提示:

1. 尽管大多数在线用户建议使用最大线程“/MT:128”以获取最佳性能...请不要在非常大的文件中使用“/MT:128”...那是一个大错误,它会导致您的驱动器性能在几次运行后急剧下降...它会创建非常高的碎片或甚至在某些情况下导致文件系统失败,最终您将花费宝贵的时间尝试恢复原始分区和所有搞笑的事情。而且,它的速度比不使用“/MT:128”要慢4-6倍!!

对于非常大的文件:

  1. 仅使用一个线程“/MT:1”| 影响: 巨大
  2. 必须使用“/J”禁用缓冲区 | 影响: 高
  3. 使用“/NP”与“/LOG:file”,并且不要通过“/TEE”输出到控制台 | 影响: 中等。
  4. 将“/LOG:file”放在与源或目标不同的驱动器上| 影响: 低。

对于常规大文件:

  1. 使用多个线程,我不会超过“/MT:4”| 影响: 巨大
  2. 如果目标磁盘具有较低的缓存规格,则使用“/J”禁用缓冲区 | 影响: 高
  3. & 4同上。

对于数千个小文件:

  1. 尽情使用多个线程,首先我会从16开始,并乘以2,同时监视磁盘性能。一旦它开始下降,我将回到前一个值并坚持下去| 影响: 巨大
  2. 不要使用“/J” | 影响: 高
  3. 使用“/NP”与“/LOG:file”,并且不要通过“/TEE”输出到控制台 | 影响:
  4. 将“/LOG:file”放在与源或目标不同的驱动器上 | 影响:

我尝试了一个本来工作正常的robocopy调用,但它抱怨说“/IM”无法识别。具体而言,它报告“/IM”为“无效参数”。 - RBerman
该网站列出了参数,包括/IM /IS /IT。或者只需尝试使用“Robocopy /?”命令。 - Hel O'Ween
@RBerman /IM 是 ROBOCOPY 的后期添加功能,但我认为在这种情况下可以省略。 - kofifus

1
我使用Robocopy命令,通过覆盖文件的方式设置了正确的文件权限,这是针对一个家目录的所有文件夹都在相应用户的桌面上的情况而设计的。通过快捷方式可以访问这些文件夹,但用户无法看到即使它存在。请注意,html标签已被保留。
FOR /F "tokens=*" %G IN ('dir /b') DO robocopy  "\\server02\Folder with shortcut" "\\server02\home\%G\Desktop" /S /A /V /log+:C:\RobocopyShortcut.txt /XF *.url *.mp3 *.hta *.htm *.mht *.js *.IE5 *.css *.temp *.html *.svg *.ocx *.3gp *.opus *.zzzzz *.avi *.bin *.cab *.mp4 *.mov *.mkv *.flv *.tiff *.tif *.asf *.webm *.exe *.dll *.dl_ *.oc_ *.ex_ *.sy_ *.sys *.msi *.inf *.ini *.bmp *.png *.gif *.jpeg *.jpg *.mpg *.db *.wav *.wma *.wmv *.mpeg *.tmp *.old *.vbs *.log *.bat *.cmd *.zip /SEC /IT /ZB /R:0

正如您所看到的,有许多文件类型我设置为忽略(以防万一),只需根据您的需求或情况进行设置。

它已在Windows Server 2012上测试,并且每个开关都在Microsoft和其他网站上有文档记录。


1
你好,欢迎来到SO。我已经编辑了你的答案,试图使其更易理解,但我不确定这是否是你的意思。无论如何,你已经描述了你的场景(我并没有真正理解,抱歉),但你没有解释你的命令做什么,而且由于它是一个复杂的命令,弄清楚它并不是微不足道的。我建议[编辑]你的答案,并提供至少一个关于这个命令做什么以及如何做的概述。此外,你确定你正在回答原始问题,即如何强制Robocopy覆盖看起来相同的文件吗? - Fabio says Reinstate Monica

0
补充FahadBA的答案在这里,我能够使用Robocopy的/IM开关解决这个问题,只需进行一个小的更改: robocopy /IM /IS /TIMFIX "源路径" "目标路径" "文件" 因为在此之前我已经将文件复制到目录中,仅使用/IS开关无法解决问题,而且我希望确保文件保持相同的修改时间戳,因为这对我的应用程序很重要。添加/TIMFIX开关将强制所有路径(包括UNC路径,即\\服务器名\命名法)具有相同的时间戳,从而解决了@AMissico在答案的评论部分在这里中报告的问题,简化了robocopy的命令(避免了该答案中使用xcopy的笨拙解决方法)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接